Patterns. Паттерн Factory Method (Фабричный метод). Реализация структуры, простейший случай

Паттерн Factory Method (Фабричный метод). Реализация структуры, простейший случай


Содержание


Поиск на других ресурсах:

1. Общие сведения. Случаи применения. Структура паттерна. Рисунок

Паттерн Factory Method (Фабричный Метод) также называется Virtual Constructor (Виртуальный конструктор). Это паттерн, порождающий классы.

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

Паттерн следует применять в следующих случаях:

  • класс не зависит от конкретного типа создаваемого продукта;
  • класс не знает о типе продукта, который должен быть создан;
  • продукты, которые необходимо создавать, должны или могут определяться в производных классах.

Общая структура паттерна FactoryMethod изображена на рисунке 1.

Структура паттерна FactoryMethod

Рисунок 1. Структура паттерна FactoryMethod

Участниками паттерна являются:

  • Creator – абстрактный разработчик. Содержит абстрактный метод создания экземпляра продукта типа Product;
  • ConcreteCreator – конкретный разработчик. Реализует метод создания экземпляра продукта;
  • Product – интерфейс, являющийся абстрактным продуктом. Служит для представления конкретных продуктов;
  • ConcreteProduct – конкретный продукт. Реализует интерфейс Product абстрактного продукта;
  • Client – клиент, обращающийся к фабричному методу FactoryMethod() создателя Creator для получения экземпляра продукта.

Между участниками паттерна можно выделить следующие связи:

  • Абстрактный класс (интерфейс) Creator определяет абстрактный метод FactoryMethod(), возвращающий ссылку на Product;
  • ответственность за создание конкретного продукта лежит на подклассах класса Creator;
  • Класс ConcreteCreator реализует метод FactoryMethod(), создающий продукт – объект класса ConcreteProduct.

 

2. Реализация паттерна FactoryMethod. Программа на C++

Ниже приведен программный код на языке C++, реализующий паттерн Factory Method, структура которого изображена на рисунке 1.

#include <iostream>
using namespace std;

// ----------- Классы продукта ------------------------
// Абстрактный продукт
class Product abstract
{
public:
  virtual void Set(string) = 0;
  virtual string Get() abstract;

  // Некоторые операции
  virtual void Operation() abstract;
};

// Конкретный продукт
class ConcreteProduct : Product
{
private:
  string data;

public:
  // Конструктор
  ConcreteProduct(string data = "") : data(data)
  { }

  // Методы доступа
  void Set(string data) { this->data = data; }
  string Get() { return data; }

  // Вывести внутреннее состояние
  void Print(string msg)
  {
    cout << msg << " => " << data << endl;
  }

  // Реализация метода Operation()
  void Operation() override
  {
    // вывести название метода и данные
    cout << "ConcreteProduct::Operation() => " << data << endl;
  }
};

// Абстрактный класс Creator - абстрактный разработчик
class Creator abstract
{
public:
  virtual Product* FactoryMethod(string) abstract;
};

// Конкретный разработчик
class ConcreteCreator : Creator
{
public:
  // Метод создания экземпляра продукта
  Product* FactoryMethod(string data) override
  {
    // Некоторая работа
    return (Product*)new ConcreteProduct(data);
  }
};

void main()
{
  // Паттерн FactoryMethod
  // Клиентский код
  // Использование продукта
  Product* product = nullptr;

  // Создать разработчика продукта
  ConcreteCreator creator;

  // Получить продукт
  product = creator.FactoryMethod("Data of product.");

  // Вызвать операции
  product->Operation();
  ((ConcreteProduct*)product)->Print("Product");

  if (product)
    delete product;
}

 

3. Результаты использования паттерна

Для паттерна Factory Method можно определить следующие результаты.

1. Абстрактный класс Creator зависит от конкретного типа создаваемых продуктов.

Ответственность за создание продукта лежит на классах, унаследованных из класса Creator (реализующих интерфейс Creator).

Преимущество в том, что благодаря интерфейсу Creator происходит постепенное уточнение конкретных продуктов в соответствующих подклассах.

Недостатком является то, что при добавлении новых типов продуктов возникает необходимость в создании подклассов класса Creator. Это, в свою очередь, может привести к неоправданному росту подклассов.

2. Паттерн объединяет две иерархии классов: создателей продукта и самих продуктов.

3. Существует возможность объявления фабричного метода по умолчанию.

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

4. В случае реализации класса Creator в качестве шаблонного (Creator<T>) класс продукта может передаваться как тип-параметр T. В таком случае, фабричный метод будет создавать объекты обобщенного типа-параметра T и при определении нового типа продукта не обязательно использовать наследование.

 

4. Преимущества и недостатки паттерна

К преимуществам паттерна Factory Method можно отнести следующие.

  1. Клиенту не нужно уделять значительное внимание конфигурированию экземпляра конкретного создателя (ConcreteCreator) специфическим продуктом.
  2. Каждый продукт (ConcreteProduct) может конфигурироваться параметрами, о которых знает только конкретный создатель (ConcreteCreator).
  3. Клиент взаимодействует с конкретными создателями (ConcreteCreator) через абстрактного создателя (Creator). Таким образом, клиент располагает информацией только об абстрактном создателе.

Недостатком паттерна является то, что тип продукта (ConcreteProduct) для конкретного класса создателя (ConcreteCreator) определяется на этапе компиляции (статически) и может изменяться на этапе выполнения.

 


Связанные темы