Абстрактная фабрика. Abstract Factory.

Предположим, Вы пишете игру. Стратегию. У Вас есть классы "Ферма", "Фермер", "Рыцарь". Где-то в коде для производства экземпляров Вы пишете

CFarm* theFarm = new CFarm;
CFarmer* theFarmer = new CFarmer;
CKnight* theKnight = new CKnight;

или наподобие того. Они взаимодействуют между собой, могут друг друга производить или уничтожать, изменять состояния. Но стратегия предполагает противника. Пусть будут гномы, и они представлены классами "Шахта", "Шахтер", "Топорник": CMine, CMiner, CAxer. Алгоритм (движок, engine) принципиально один и тот же, и будет скучно переписывать куски кода только из-за того, что конструкторы НЕВИРТУАЛЬНЫЕ. Следовательно, нужно как-то виртуализовать производство юнитов, а способ для этого один: выделить производство в специальный класс (фабрику объектов), и в нем объявить виртуальный метод производства.

Подробнее:

1. Сходные по смыслу юниты порождаем от одного класса, CFarm, CMine от CProductive; CFarmer, CMiner от CWorker, CKnight, CAxer от CWarrior.

2. Объявляем абстрактный класс-фабрику CAbstractFactory, имеющую чистые виртуальные методы

CProductive* CreateProductive();
CWorker* CreateWorker();
CWarrior* CreateWarrior();

3. Для каждой расы создаем конкретную фабрику, методы которой возвращают указатели на соответствующие юниты. То есть людская фабрика производит фермы и рыцарей, а гномья - шахты и топорников.

4. В движке прописываем указатель типа CAbstractFactory*, то есть он указатель на абстрактную фабрику, а на самом деле он указывает на настоящую фабрику.

5. Движок получает экземпляры юнитов только через фабрику. Теперь Ваша гама совершенно отвязана от вида цивилизации, и более того, Вы можете изменять производимые юниты прозрачно от движка: разделите фермеров на свинарей и овцеводов - движок не заметит подмены, если у них единый интерфейс.

Это структура паттерна. Клиент использует продукты, и обращается за их производством к абстрактной фабрике.


By Albert Makhmutov.



Опубликовал admin
1 Авг, Воскресенье 2004г.



Программирование для чайников.