Абстрактная фабрика предоставляет интерфейс, позволяющий порождать семейства объектов c заданными интерфейсами. При этом их реализации могут варьироваться.
Данный шаблон используется в случае, если:
- система не должна зависеть от способа создания и реализации входящих в нее объектов;
- (и) система работает с семействами объектов;
- (и) входящие в семейство объекты должны использоваться совместно.
Обратите внимание, клиентский код использует в работе только интерфейсы. Реализации Абстрактной фабрики и порождаемых ею объектов скрыты. Такой подход уменьшает зависимости между объектами и повышает гибкость, за счет возможности изменения реализаций.
Часто можно увидеть совместное использование Абстрактной фабрики с другими шаблонами:
- Одиночка – если не требуется больше одного ее экземпляра;
- Фабричный метод – для создания ее экземпляров.
Реализация шаблона в общем виде
- разрабатываем интерфейсы объектов семейства и Абстрактной фабрики;
- создаем семейства объектов и реализации Абстрактной фабрики для них;
- в программе, например, в зависимости от версии ОС, конфигурации или другого параметра, порождается необходимая реализация Абстрактной фабрики.
- в дальнейшем используется только интерфейсы как Абстрактной фабрики, так и порождаемых ей объектов.
Примеры реализации
Вначале создадим интерфейс IEngine, являющийся абстрактным представлением выпускаемого заводом двигателя. Интерфейс имеет единственный виртуальный метод ReleaseEngine();
Далее создадим конкретный класс японского двигателя JapaneseEngine, реализующий интерфейс IEngine и создадим класс российского двигателя RussianEngine, так же реализующий этот интерфейс.
На производстве будут выпускаться автомобили, которые будет описывать интерфейс ICar. В нем будет метод ReleaseCar в котором в качестве аргумента будет выступать выпускаемый двигатель.
Реализуем интерфейс ICar в классе JapaneseCar, представляющий выпуск данного автомобиля. А так же класс RussianCar.
Создадим интерфейс фабрики по производству автомобилей IFactory, который будет содержать два метода - CreateEngine и CreateCar.
Данный интерфейс будут реализовывать классы JapaneseFactory и RussianFactory.
Посмотрим применение абстрактной фабрики.