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) визначається на етапі компіляції (статично) і не може змінюватись на етапі виконання.

 


Споріднені теми