Шаблон проектирования Abstract Factory


На главную
Содержание

Позволяет создавать группы объектов, которые реализуют одно и то же поведение. Группа объектов создается одной абстрактной фабрикой. Предоставляет единый интерфейс для создаваемых объектов, которые относятся к одному семейству. При этом не имеет значения, к какому классу принадлежат объекты.
При использовании Abstract Factory система становится более гибкой, поскольку можно подменять связанные или зависимые объекты, сохраняя при этом их интерфейсы.

E. Gamma, R. Helm, R. Johnson, J. Vlissides определяют назначение шаблона Abstract factory следующим образом: шаблон Abstract Factory "предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов".

Поясним принцип применения шаблона на небольшом примере. Допустим существует класс SendData, объект которого обрабатывает некие данные и может посылать их другим объектам. Отправляемые данные должны быть представлены в различном формате в зависимости от того, какому объекту они адресуются. Если класс SendData сам будет и отправлять данные, и определять их формат, он получится перегруженным. Поэтому имеет смысл ввести новый класс (абстрактную фабрику), который и будет заниматься определением формата данных и создавать объекты FormattedData, содержащие данные нужного типа, для отправки адресатам. Сам класс AbstractFactory является абстрактным и только предоставляет нужный интерфейс. Форматированные данные создаются потомками класса AbstractFactory.

Гибкость системы в данном случае заключается в том, что при добавлении нового формата данных (например, FormattedData3) нам не нужно изменять класс SendData.

Схема взаимодействия классов в приведенной ниже реализации:
Классы шаблона Abstract Factory


Приведем реализацию описанного выше примера:


Реализация на C++

//общий интерфейс для данных любого формата
class FormattedData {
//...
};
//конкретный формат
class FormattedData1 : public FormattedData {
//...
};
//другой конкретный формат
class FormattedData2 : public FormattedData {
//...
};

//абстрактная фабрика
class AbstractFactory {
public:
virtual FormattedData* createFormattedData() = 0;
};
//фабрика для создания объектов, содержащих данные
//нужного формата
class FormatFactory : public AbstractFactory {
public:
FormattedData* createFormattedData() {
if(/* some condition */) {
return new FormattedData1();
}
else {
return new FormattedData2();
}
}
};

//использование абстрактной фабрики
int main() {
FormatFactory* pfactory = new FormatFactory();
FormattedData* pdata = pfactory->createFormattedData();
//send data
//...
if(pfactory)delete pfactory;
if(pdata)delete pdata;
return 0;
}


Реализация на C#

//общий интерфейс для данных любого формата
class FormattedData {
//...
}
//конкретный формат
class FormattedData1 : FormattedData {
//...
}
//другой конкретный формат
class FormattedData2 : FormattedData {
//...
}

//абстрактная фабрика
abstract class AbstractFactory {
abstract public FormattedData createFormattedData();
}
//фабрика для создания объектов, содержащих данные
//нужного формата
class FormatFactory : AbstractFactory {
override public FormattedData createFormattedData() {
if(/* some condition */) {
return new FormattedData1();
}
else {
return new FormattedData2();
}
}
}

//клиент, использующий фабрику
public class SendData {
public static int Main(string[] args) {
FormatFactory factory = new FormatFactory();
FormattedData data = factory.createFormattedData();
//send data
//...
return 0;
}
}

Содержание
На главную

Rambler's Top100
Хостинг от uCoz