Главная » Delphi » Шаблон Abstract Factory (Абстрактная фабрика)

0

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

Итак, Абстрактная фабрика (рис. 7.2) производит объекты, работа с которыми происходит через абстрактный интерфейс, а способы его реализации скрыты. При этом конкретные объекты, производимые фабрикой, могут сильно различаться по своей внутренней структуре — главное, чтобы они поддерживали заданный интерфейс.

Рис. 72. Абстрактная фабрика в Дизайнере модели

Разработчик взаимодействует лишь с интерфейсом lAbstractProduct абстрактных продуктов — некоторых классов с внешне неизвестной структурой и реализацией, поддерживающих этот универсальный интерфейс. А создаются продукты с помощью интерфейса lAbstraclFactory. Реальная фабрика TConcreteFactory реализует фабричный интерфейс lAbstractFactory, а конкретный класс TConcreteProduct реализует абстрактный интерфейс lAbstractProduct.

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

lAbstractProduct = interface end;

lAbstractFactory = interface

function CreatelAbstractProduct: lAbstractProduct; end;

Добавим в» класс lAbstractProduct новый метод Funcl.

lAbstractProduct = interface

function Funcl: integer; end;

В реализующем его классе TConcreteProduct, соответственно, надо запрограммировать метод Fund.

TConcreteProduct = class(TObject, IAbstractProduct) function Fund: integer-

end;

function TConcreteProduct.Fund: integer;

begin Result := 5;

end;

Создание данного продукта в коде уже было сформировано автоматически в момент добавления шаблона к модели.

function TConcreteFactory.CreatelAbstractProduct: IAbstractProduct;

begin

Result := TConcreteProduct.Create();

end;

Теперь добавим к шаблону новый конкретный продукт — выберем объект AbstractFactory на диаграмме (образ шаблона в овале) и в его контекстном меню дадим команду Add > Concrete Product (Добавить > Конкретный продукт). К модели добавится новый класс, который мы назовем TConcreteProduct2. Он автоматически наследует интерфейс IAbstractProduct, поэтому в нем также надо указать реализацию метода Fund.

TConcreteProduct2 = class(TObject, IAbstractProduct) public

function Fund: integer-

end;

function TConcreteProduct2.Fund: integer;

begin Result := 10;

end;

Кроме того, требуется вручную (начиная с Дизайнера модели) добавить в Абстрактную фабрику метод создания нового продукта (обратите внимание, что каждая функция возвращает один и тот же абстрактный интерфейс).

IAbstractFactory = interface

function CreatelAbstractProduct: IAbstractProduct; function CreateIAbstractProduct2: IAbstractProduct;

end;

И в реальную фабрику — также, только уже с реализацией метода создания нового продукта.

TConcreteFactory = class(TObject, IAbstractFactory) public

function CreatelAbstractProduct: IAbstractProduct; function CreateIAbstractProduct2: IAbstractProduct;

end;

function TConcreteFactory.CreateIAbstractProduct2: IAbstractProduct;

begin

Result := TConcreteProduct2.Create();

end;

На этом реализация Абстрактной фабрики завершена, и можно перейти к ее использованию. В обработчике нажатия на кнопку надо описать две переменные интерфейсов.

var cpl: IAbstractProduct; afls IAbstractFactory;

С их помощью мы и будем организовывать доступ к ресурсам фабрики. В коде самого обработчика укажем команду создания реальной фабрики, реализующей интерфейс IAbstractFactory

afl := TConcreteFactory.Create;

и команду создания с помощью фабрики конкретного продукта

cpl := afI.CreateIAbstractProduct2;

Теперь через интерфейс IAbstractProduct мы можем обращаться к конкретному экземпляру любого из классов TConcreteProduct и TConcreteProduct2.

procedure TWinForm.Buttonl_Click(sender: System.Object; e: System.EventArgs);

var cpl: IAbstractProduct; afl: IAbstractFactory;

begin

afl := TConcreteFactory.Create;

cpl := afl.CreatelAbstractProduct;

label 1. Text : = cpl. Fund . ToString ;

end;

В данном случае в поле labell будет показано значение 5, а в следующем случае:

procedure TWinForm.Buttonl_Click(sender: System.Object; e: System.EventArgs);

var cpl: IAbstractProduct;

afl: IAbstractFactory; begin

afl := TConcreteFactory.Create;

cpl := afl.CreateIAbstractProduct2; // создание экземпляра TConcreteProduct2

label 1 .Text := cpl. Fund .ToString;

end;

будет выведено значение Ю.

Бобровский С. И. Технологии Delphi 2006. Новые возможности. — СПб.: Питер, 2006. — 288 е.: ил.

По теме:

  • Комментарии