|
|
|||||
Регистрация: Mar 2009
Сообщений: 51
|
Фабрика не должна отдавать объекты?
Здравствуйте!
Изучаю замечательную книгу Шаблоны проектирования (Design Patterns) O'REILLY. Первый шаблон в этой книге - Фабричный метод (Factory Method). Этот шаблон помогает создавать множество типов объектов через обращение в одну общую точку, так называемую фабрику. Во всех примерах в этой книге фабрика не отдает объект. Она создает объект и сама же выполняет манипуляции с ним. Но если я хочу управлять объектом вне фабрики? Правильно ли будет изменить фабрику так, чтобы она возвращала этот объект или это противоречит шаблону? Приведу примерный код минималистического примера из книги: 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(); } } } public function doStuff():void { var object:IObject = this.factoryMethod(); object.manipulate(); } public function doStuff():IObject { var object:IObject = this.factoryMethod(); object.manipulate(); return object; } 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 } Если да, то как управлять объектами после создания в фабрике? Поделитесь пожалуйста опытом |
|
|||||
[+4 06.05.14]
|
Что то как то странно, поидее фабрика должна выглядеть так
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 коробок, но знайте что если пнуть коробку, она сама откроется Тоесть не фабрика должна открывать коробку, а клиент С другой стороны тип фабрики может быть другой. Например - ремонтная мастерская, это тоже фабрика , но по ремонту, и тогда мы уже говорим фабрике - почините мне 5 телевизиров 1ой марки )))
__________________
Марк Tween |
|
|||||
Не надо путать "абстрактную фабрику" и "фабричный метод".
А паттерн "просто фабрика" не является GoF-овским, если вообще является паттерном (хотя штука полезная и используется) Фабричный метод вприципе может подразумевать использование объекта самим собой. Это для изменения поведения объекта через наследование нужно и, на сам деле он то как раз на практике и используется и _очень_ часто, а "абстрактная фабрика" - не помню ни одного случая в своей практике. Ну может пару раз было. |
|
|||||
Регистрация: Mar 2009
Сообщений: 51
|
@in4core : спасибо за пример)
@expl : А зачем нужна "абстрактная фабрика"? Просто для подготовки объектов в одном месте? И "простая фабрика" == "абстрактная фабрика" ? |
|
|||||
[+4 06.05.14]
|
Ну абстрактная это так скажем пример. Это как говорить *в общем*. Так же как MVC - есть же такой паттерн, но никто ни слова не упоминает о том, что внутри могут быть реализации других паттернов и т.п.
Бред несу....)))
__________________
Марк Tween |
|
|||||
Цитата:
Она представляет собой множество фабрик с одинаковым интерфейсом. И одна фабрика производит несколько типов объектов Классический пример приводят - это разные скины всех контролов. Т.е. одна фабрика генерит контролы аля виндовс, другая - аля мак. А тот кто эти контролы располагает и связывает в игре просто при запуске подставляет одну из фабрик и везде if-ы не пишет. Но штука громоздкая, потому не используется, или используется изредка во фреймворках. Цитата:
Простая фабрика это просто что угодно с публичным методом/методами newSomeObject():SomeObject. Есть статическая простая фабрика - её методы статические. Абстрактная фабрика подразумевает, что фабрик несколько и они имеют общий интерфейс - абстрактную фабрику Ну вот не хочется вам кнопку по 10 раз настраивать в 10 местах - вы делаете метод "newCustomizedButton", в котором её создаёте и настраиваете. А во всех частях вместо 5 строк кода пишете одну - MyFactory.newCustomizedButton(); Это простая статическая фабрика Или вот Вы создаете список с рендерерами во flex. Чтобы он отображал рендереры класса MyRenderer вы туда передаёте фабрику с интерфейсом: Например это ClassFactory, ну new ClassFactory(MyRenderer) вы туда передаёте. А вот это _простая_ нестатическая фабрика А вот если бы было так: Это уже тянет на абстрактную фабрику. Но обычно просто 2 ClassFactory проще передать, чем этот интерфейс городить. Хоня не всегда. Последний раз редактировалось expl; 21.09.2012 в 19:36. |
|
|||||
Регистрация: Mar 2009
Сообщений: 51
|
Цитата:
То есть для каждого рендера свой интерфейс? Я думал создается просто несколько рендеров с одним интерфейсом и несколько фабрик, которые работают через единый интерфейс рендера. Одна фабрика - один тип рендера? Нет? Последний раз редактировалось Fintch; 22.09.2012 в 11:39. |
|
|||||
Вы наверно не разобрались потому что я искусственный пример привёл.
Но объясню этот дурацкий пример до конца: Цитата:
Т.е. есть одна фабрика (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 |
|
|||||
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
Я использовал абстрактные фабрики довольно часто.
Вот пример. У меня есть абстрактный плагин в котором определено создание визуального объекта и прочее. там есть строчка в методе создания вьюшек по модели: В наследниках абстрактного плагина я инжектирую нужную фабрику _viewFactory, и в одном случае плагин по данным модели будет создавать красный кубик, в другом зелёный. Можно этого же добиться переопределением абстрактного метода createView в наследниках, но тогда начинаются проблемы с наследованием и копипастой, а фабрика позволяет использовать композицию.
__________________
Отряд Котовскага |
Часовой пояс GMT +4, время: 00:16. |
|
« Предыдущая тема | Следующая тема » |
|
|