![]() |
|
||||||||||
|
|||||
|
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Начав читать интереснейшие статьи про различные паттерны проектирования, я стал их заложником.
Все они хорошие, все призваны упростить и улучшить код, но хорошее не всегда лучшее и чтобы не отклониться от курса, очень хочется, чтобы опытные, матёрые "кутюрье интернета", поделились секретами о структурировании и создании классов. И эту тему я создал не из любопытства, а как уже упомянул ранее, из-за неоднозначных слов про то, что "абстрактную фабрику" в проектах не используют. Хоть такой паттерн и есть, но он как я понял не для жизни. И там же говорилось о "обычной фабрике" о которой я не понял не чего.. ГУРУ ? Добавлено через 13 часов 26 минут class Factory { private static const ITEMS:Vector.<Class> = Vector.<Class>([Sword, Shield, Boots]); public static function createItem(id:uint):IItem { return new ITEMS[id]() as IItem; } } // ... somewhere var item:IItem = Factory.createItem(2); // новый экземпляр класса Boots Ну ведь так же и "абстрактная фабрика" устроенна - это тоже класс, экземпляр которого мы не создаем... Последний раз редактировалось Akopalipsis; 12.08.2013 в 22:15. |
|
|||||
|
Так и есть. Просто в обиходе не заморачиваются и абстрактную фабрику называют фабрикой. Паттерн фабрика впринципе один. Тут путаницы быть не должно.
И там были еще вопросы про фабричный метод. Фабричный метод это фабричный метод. Фабричный метод может быть одним из вариантов реализации фабрики.
__________________
Кто к нам с чем для чего - тот у нас того от того. |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
какой-то ужас написали... ладно, названия классов и методов перепутаны, я еще могу как-то сопоставить. Но оверрайд не может быть с другой сигнатурой
Цитата:
А вот абстрактная тем и отличается, что её экземпляр создать невозможно, потому что он абстрактный. (в моем примере Фабричного метода это был бы интерфейс ЯЗавод. Вы ведь не можете создать экземпляр интерфейса?). Вы создаете экземпляры классов-наследников, и используете их, подставляя нужный. ОК, давайте простой пример. Шахматы. Есть белые и черные фигуры. Есть Абстрактная фабрика с шестью методами, создающими экземпляры фигур — коня, короля, ферзя и т.д. И два класса-наследника, белая фабрика и черная фабрика. Ваше приложение знает ТОЛЬКО абстактную фабрику, у которой можно запросить коня или ладью. Оно не знает, будет конь белым или черным. Или серобуромалиновым в крапинку. Кто-то свыше устанавливает режим "белый", и место абстрактной фабрики занимает конкретная Белая фабрика, которая может отдавать только белых коней и королей. Вот и весь фокус. Это всего-лишь обычный полиморфизм. Клиент не знает, с каким конкретно классом работает, потому что работает с абстрактным суперклассом или интерфейсом. И какой конкретный класс будет производить набор фигур, решается в другом месте. В этом суть паттерна Абстрактная Фабрика. Похоже это хоть чем-то на обычный класс, производящий экземпляры? Смотреть то надо не на результат, а на решаемую задачу. А задачи у них абсолютно разные.
__________________
Reality.getBounds(this); |
|
|||||
|
.
|
Абстрактная фабрика производит конкретные фабрики, которые вы используете для получения конкретного продукта.
// новый экземпляр фабрики типа IHouseFactory. const factory:IHouseFactory = AbstractFactory.create("И-522а"); Все фабрики, выпускаемые фабрикой AbstractFactory имеют тип интерфейса IHouseFactory, который умеет производить части дома: фундамент createBasement, окна createWindow, перекрытия, лестничные пролеты и прочая конкретного типа домов (серии). const basement:IBasement = factory.createBasement(); // Фундамент серии "И-522а" готов! const window:IWindow = factory.createWindow(); // Окно серии "И-522а" готово! basement.addWindow(window); // Собрали дом серии И-522а; ЗЫ. Почитателям друпального агрегатирования привет от инди-разработчика! |
|
|||||
|
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Цитата:
Начну с "Абстрактной Фабрики". package chess.factory { import flash.display.Sprite; internal class Figure extends Sprite { //метод для переопределения internal function drawFigure():void { // } } } package chess.factory { internal class BlackHorse extends Figure { override internal function drawFigure():void { trace('BlackHorse'); } } } package chess.factory { internal class BlackQueen extends Figure { override internal function drawFigure():void { trace('BlackQueen'); } } } package chess.factory { internal class WhiteHorse extends Figure { override internal function drawFigure():void { trace('WhiteHorse'); } } } package chess.factory { internal class WhiteQueen extends Figure { override internal function drawFigure():void { trace('WhiteQueen'); } } } package chess.factory { public class BlackFigure extends FactoryFigure { public static const BLACK_HORSE : uint = 0x143423; public static const BLACK_QUEEN : uint = 0x331236; override public function createFigure(id:uint):Figure { if (id == BLACK_HORSE) { trace('BlackFigure create BLACK_HORSE'); return new BlackHorse(); } else if (id == BLACK_QUEEN) { trace('BlackFigure create BLACK_QUEEN'); return new BlackQueen(); } else { trace('ERROR BLACKFIGURE'); throw new Error('ERROR'); } } } } package chess.factory { public class WhiteFigyre extends FactoryFigure { public static const WHITE_HORSE : uint = 0xFFFFFF; public static const WHITE_QUEEN : uint = 0xE4E7ED; override public function createFigure(id:uint):Figure { if (id == WHITE_HORSE) { trace('WhiteFigyre create WHITE_HORSE'); return new WhiteHorse(); } else if (id == WHITE_QUEEN) { trace('WhiteFigyre create WHITE_QUEEN'); return new WhiteQueen(); } else { trace('ERROR WHITEFIGYRE'); throw new Error('ERROR'); } } } } package chess.factory { import flash.errors.IllegalOperationError; public class FactoryFigure { public function draw(id:uint):void { var figure:Figure = createFigure(id); } public function createFigure(id:uint):Figure { throw new IllegalOperationError('ERROR'); return null; } } } package chess { import chess.factory.BlackFigure; import chess.factory.FactoryFigure; import chess.factory.WhiteFigyre; import flash.display.Sprite; public class Main extends Sprite { public function Main() { /** * public static const WHITE_HORSE : uint = 0xFFFFFF; * public static const WHITE_QUEEN : uint = 0xE4E7ED; */ var whiteHorse:FactoryFigure = new WhiteFigyre(); whiteHorse.draw(0xFFFFFF); /** * public static const BLACK_HORSE : uint = 0x143423; * public static const BLACK_QUEEN : uint = 0x331236; */ var blackHorse:FactoryFigure = new BlackFigure(); blackHorse.draw(0x143423); } } } |
|
|||||
|
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Цитата:
Если я в классе Main ( как в моём примере ) сразу обращаться к классу Белые фигуры, то это и будет "просто фабрика" ? |
|
|||||
|
.
|
Нет BlackFigure, WhiteFigyre. Есть
|
|
|||||
|
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Цитата:
|
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
dimarik, хороший пример, спасибо)))
У GoF тоже нормальный пример (мой конечно не очень логичен)) — есть некий интерфейс (GUI) приложения, скажем кнопка, скроллбар, дропменю и чекбокс. И есть два (или больше) стилей для отображения этого интерфейса. Допустим, приложение может выглядеть в стиле Windows, а может в стиле MacOS. Самому приложению совершенно все равно, как выглядят эти кнопки и бары, но они, конечно же, должны соответствовать своим типам, чтобы можно было задавать им значения и запрашивать их. У приложения есть класс или функция, который должен создать и расставить элементы интерфейса. Он обращается к фабрике, которая представлена Абстрактным Классом или Интерфейсом, и получает от нее экземпляры кнопок и т.п. var factory:IGUIFactory; //... где-то происходит инициализация factory //... допустим таким образом: factory = AbstractFactory.create("MacOS"); //... затем фабрика создает экземпляры var scrollbar:IScrollbar = factory.createScrollbar(); var button:IButton = factory.createButton(); var checkbox:ICheckbox = factory.createCheckbox(); var menu:IMenu = factory.createMenu();
__________________
Reality.getBounds(this); |
![]() |
![]() |
Часовой пояс GMT +4, время: 10:41. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|