Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 21.09.2012, 18:32
Fintch вне форума Посмотреть профиль Отправить личное сообщение для Fintch Найти все сообщения от Fintch
  № 1  
Ответить с цитированием
Fintch
 
Аватар для Fintch

Регистрация: Mar 2009
Сообщений: 51
Question Фабрика не должна отдавать объекты?

Здравствуйте!

Изучаю замечательную книгу Шаблоны проектирования (Design Patterns) O'REILLY.
Первый шаблон в этой книге - Фабричный метод (Factory Method).

Этот шаблон помогает создавать множество типов объектов через обращение в одну общую точку, так называемую фабрику.
Во всех примерах в этой книге фабрика не отдает объект. Она создает объект и сама же выполняет манипуляции с ним.

Но если я хочу управлять объектом вне фабрики?
Правильно ли будет изменить фабрику так, чтобы она возвращала этот объект или это противоречит шаблону?

Приведу примерный код минималистического примера из книги:
Код AS3:
package example {
 
    public interface IObject {
 
        function manipulate():void;
 
    }
 
}
 
package example {
 
    internal class Object1 implements IObject {
 
        public function Object1():void {
 
            super();
 
        }
 
        public function manipulate():void {
 
            trace("Doing stuff with Object1");
 
        } 
 
    }
 
}
 
package example {
 
    internal class Object2 implements IObject {
 
        public function Object2():void {
 
            super();
 
        }
 
        public function manipulate():void {
 
            trace("Doing stuff with Object2");
 
        } 
 
    }
 
}
 
package example {
 
    public class Factory {
 
        // Abstract Class
        public function Factory():void {
 
            super();
 
        }
 
        public function doStuff():void {
 
            var object:IObject = this.factoryMethod();
            object.manipulate();
 
        }
 
        protected function factoryMethod():IObject {
 
            // abstract method
            return null;    
 
        } 
 
    }
 
}
 
package example {
 
    public class Factory1 extends Factory {
 
        public function Factory1():void {
 
            super();
 
        }
 
        override protected function factoryMethod():IObject {
 
            return new Object1();    
 
        } 
 
    }
 
}
 
package example {
 
    public class Factory2 extends Factory {
 
        public function Factory2():void {
 
            super();
 
        }
 
        override protected function factoryMethod():IObject {
 
            return new Object2();    
 
        } 
 
    }
 
}
 
package {
 
    public class Main extends Sprite {
 
        public function Main():void {
 
            super();
 
            var factory1:Factory1 = new Factory1();
            var factory2:Factory2 = new Factory2();
 
            factory1.doStuff();
            factory2.doStuff();
 
        }
 
    }
 
}
Вот в этом месте:
Код AS3:
public function doStuff():void {
 
    var object:IObject = this.factoryMethod();
    object.manipulate();
 
}
Можно так:
Код AS3:
public function doStuff():IObject {
 
    var object:IObject = this.factoryMethod();
    object.manipulate();
    return object;
 
}
И в Main так:
Код AS3:
public function Main():void {
 
    super();
 
    var factory1:Factory1 = new Factory1();
    var factory2:Factory2 = new Factory2();
 
    var object1:IObject = factory1.doStuff();
    var object2:IObject = factory2.doStuff();
 
    // затем манипуляции с object1 и object2
 
}
Или все это противоречит замыслу фабрики?
Если да, то как управлять объектами после создания в фабрике?
Поделитесь пожалуйста опытом

Старый 21.09.2012, 18:38
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 2  
Ответить с цитированием
in4core
[+4 06.05.14]
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
Что то как то странно, поидее фабрика должна выглядеть так

Код AS3:
public function Main():void {
 
    super();
 
    var factory1:Factory1 = new Factory1();
    var factory2:Factory2 = new Factory2();
 
    var object1:IObject = factory1.getObject();
    var object2:IObject = factory2.getObject();
 
    // затем манипуляции с object1 и object2
    object1.manipulate();
 
}
Толи лыжи не едут, толи книга че то врет

Тоесть логично рассуждая : Клиент звонит на фабрику и спрашивает , а не могли ли бы вы мне завернуть 5 коробок дюлей? Ему говорят конечно - вот вам 5 коробок, но знайте что если пнуть коробку, она сама откроется

Код AS3:
var box:IBox = BoxesFactory.getBox();
box.kick()
Тоесть не фабрика должна открывать коробку, а клиент

С другой стороны тип фабрики может быть другой.
Например - ремонтная мастерская, это тоже фабрика , но по ремонту, и тогда мы уже говорим фабрике - почините мне 5 телевизиров 1ой марки )))
__________________
Марк Tween

Старый 21.09.2012, 18:47
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 3  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Не надо путать "абстрактную фабрику" и "фабричный метод".
А паттерн "просто фабрика" не является GoF-овским, если вообще является паттерном (хотя штука полезная и используется)

Фабричный метод вприципе может подразумевать использование объекта самим собой.
Это для изменения поведения объекта через наследование нужно и, на сам деле он то как раз на практике и используется и _очень_ часто, а "абстрактная фабрика" - не помню ни одного случая в своей практике. Ну может пару раз было.

Старый 21.09.2012, 19:03
Fintch вне форума Посмотреть профиль Отправить личное сообщение для Fintch Найти все сообщения от Fintch
  № 4  
Ответить с цитированием
Fintch
 
Аватар для Fintch

Регистрация: Mar 2009
Сообщений: 51
@in4core : спасибо за пример)

@expl : А зачем нужна "абстрактная фабрика"?
Просто для подготовки объектов в одном месте?
И "простая фабрика" == "абстрактная фабрика" ?

Старый 21.09.2012, 19:09
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 5  
Ответить с цитированием
in4core
[+4 06.05.14]
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
Ну абстрактная это так скажем пример. Это как говорить *в общем*. Так же как MVC - есть же такой паттерн, но никто ни слова не упоминает о том, что внутри могут быть реализации других паттернов и т.п.
Бред несу....)))
__________________
Марк Tween

Старый 21.09.2012, 19:25
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 6  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
@expl : А зачем нужна "абстрактная фабрика"?
Просто для подготовки объектов в одном месте?
В каком-то смысле можно и так сказать.
Она представляет собой множество фабрик с одинаковым интерфейсом. И одна фабрика производит несколько типов объектов
Классический пример приводят - это разные скины всех контролов. Т.е. одна фабрика генерит контролы аля виндовс, другая - аля мак. А тот кто эти контролы располагает и связывает в игре просто при запуске подставляет одну из фабрик и везде if-ы не пишет.
Но штука громоздкая, потому не используется, или используется изредка во фреймворках.

Цитата:
И "простая фабрика" == "абстрактная фабрика" ?
Нет.
Простая фабрика это просто что угодно с публичным методом/методами newSomeObject():SomeObject.
Есть статическая простая фабрика - её методы статические.
Абстрактная фабрика подразумевает, что фабрик несколько и они имеют общий интерфейс - абстрактную фабрику

Ну вот не хочется вам кнопку по 10 раз настраивать в 10 местах - вы делаете метод "newCustomizedButton", в котором её создаёте и настраиваете. А во всех частях вместо 5 строк кода пишете одну - MyFactory.newCustomizedButton(); Это простая статическая фабрика

Или вот Вы создаете список с рендерерами во flex. Чтобы он отображал рендереры класса MyRenderer вы туда передаёте фабрику с интерфейсом:
Код AS3:
interface IFactory {
   function newInstance():*
}
Например это ClassFactory, ну new ClassFactory(MyRenderer) вы туда передаёте. А вот это _простая_ нестатическая фабрика

А вот если бы было так:
Код AS3:
interface IFactory {
   function newSelectedRenderer():ISelectedRenderer// В нашем придуманном списке этот рендерер используется чтобы отображать выбранные данные
   function newRenderer():IRenderer// а этот - все остальные
}
Это уже тянет на абстрактную фабрику. Но обычно просто 2 ClassFactory проще передать, чем этот интерфейс городить. Хоня не всегда.


Последний раз редактировалось expl; 21.09.2012 в 19:36.
Старый 22.09.2012, 10:09
Fintch вне форума Посмотреть профиль Отправить личное сообщение для Fintch Найти все сообщения от Fintch
  № 7  
Ответить с цитированием
Fintch
 
Аватар для Fintch

Регистрация: Mar 2009
Сообщений: 51
Цитата:
А вот если бы было так:
Код AS3:
Код AS3:
interface IFactory {
   function newSelectedRenderer():ISelectedRenderer// В нашем придуманном списке этот рендерер используется чтобы отображать выбранные данные
   function newRenderer():IRenderer// а этот - все остальные
}
Это уже тянет на абстрактную фабрику. Но обычно просто 2 ClassFactory проще передать, чем этот интерфейс городить. Хоня не всегда.
@expl : Извините, с последним примером не могу разобраться.
То есть для каждого рендера свой интерфейс?
Я думал создается просто несколько рендеров с одним интерфейсом и несколько фабрик, которые работают через единый интерфейс рендера. Одна фабрика - один тип рендера? Нет?


Последний раз редактировалось Fintch; 22.09.2012 в 11:39.
Старый 22.09.2012, 15:45
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 8  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Вы наверно не разобрались потому что я искусственный пример привёл.
Но объясню этот дурацкий пример до конца:

Цитата:
То есть для каждого рендера свой интерфейс?
Да, чтобы подчеркнуть что эта фабрика ещё и разных интерфейсов объекты создаёт я здесь сделал их разными.

Т.е. есть одна фабрика (ARedGreed implements IFactory), которая создает красные (RedSelectedRenderer implements ISelectedRenderer) и зелёные (GreenRenderer implements IGreenRenderer)
а есть другая фабрика (ABlueYellow implements IFactory), которая создает синие (BlueSelectedRenderer implements ISelectedRenderer) и желтые (YellowRenderer implements IGreenRenderer)

А визуальный список принимает, например, в конструктор IFactory, запоминает её, и когда надо что-то выделить - создаёт новый рендерер с newSelectedRenderer, а когда не надо - просто newRenderer

Ну и понятно, что не всегда надо делать отдельные классы YellowRenderer и GreenRenderer - можно просто написть newRenderer():IRenderer { return new CommonRenderer(0xffff00); }.

P.S. Вот хороший пример зачем используются фабрики вообще: http://gonchar.me/blog/goncharposts/411

Старый 22.09.2012, 17:13
Котяра вне форума Посмотреть профиль Отправить личное сообщение для Котяра Посетить домашнюю страницу Котяра Найти все сообщения от Котяра
  № 9  
Ответить с цитированием
Котяра
буду краток
 
Аватар для Котяра

модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
Отправить сообщение для Котяра с помощью ICQ Отправить сообщение для Котяра с помощью Skype™
Я использовал абстрактные фабрики довольно часто.
Вот пример. У меня есть абстрактный плагин в котором определено создание визуального объекта и прочее.
там есть строчка в методе создания вьюшек по модели:
Код AS3:
var view: IView= _viewFactory.create(viewModel);
В наследниках абстрактного плагина я инжектирую нужную фабрику _viewFactory, и в одном случае плагин по данным модели будет создавать красный кубик, в другом зелёный.
Можно этого же добиться переопределением абстрактного метода createView в наследниках, но тогда начинаются проблемы с наследованием и копипастой, а фабрика позволяет использовать композицию.
__________________
Отряд Котовскага

Создать новую тему Ответ Часовой пояс GMT +4, время: 00:16.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 00:16.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.