Фабричний метод (шаблон проектування)

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук

Фабричний метод (англ. Factory Method) — шаблон проектування, відноситься до класу твірних шаблонів.

Зміст

Призначення [ред.]

Визначає інтерфейс для створення об'єкта, але залишає підкласам рішення про те, який саме клас інстанціювати. Фабричний метод дозволяє класу делегувати інстанціювання підкласам.

Мотивація [ред.]

Застосування [ред.]

Слід використовувати шаблон Фабричний метод коли:

  • класу не відомо заздалегідь, об'єкти яких саме класів йому потрібно створювати;
  • клас спроектовано так, щоб об'єкти, котрі він створює, специфікувалися підкласами;
  • клас делегує свої обов'язки одному з кількох допоміжних підкласів, та потрібно локалізувати знання про те, який саме підклас приймає ці обов'язки на себе.

Структура [ред.]

UML діаграма, що описує структуру шаблону проектування Фабричний метод
  • Product — продукт:
    • визначає інтерфейс об'єктів, що створюються фабричним методом;
  • ConcreteProduct — конкретний продукт:
    • реалізує інтерфейс Product;
  • Creator — творець:
    • оголошує фабричний метод, що повертає об'єкт класу Product. Creator може також визначати реалізацію за замовчанням фабричного методу, що повертає об'єкт ConcreteProduct;
    • може викликати фабричний метод для створення об'єкта Product;
  • ConcreteCreator — конкретний творець:
    • заміщує фабричний метод, що повертає об'єкт ConcreteProduct.

Стосунки [ред.]

Творець покладається на свої підкласи в означенні фабричного методу, котрий буде повертати екземпляр відповідного конкретного продукту.

Реалізація [ред.]

Приклад С++ [ред.]

# include "stdafx.h"
# include <iostream>
 
class CProduct // Product
{
public:
        virtual ~CProduct() {};
        virtual void GetName() = 0;
};
 
class CTable: public CProduct // ConcreteProduct1
{
public:
        virtual ~CTable() {};
        virtual void GetName() {
                std::cout << "It's a table!" << std::endl;
        };
};
 
class CChair: public CProduct // ConcreteProduct2
{
public:
        virtual ~CChair() {};
        virtual void GetName() {
                std::cout << "It's a chair!" << std::endl;
        };
};
 
class CBed: public CProduct // ConcreteProduct3
{
public:
        virtual ~CBed() {};
        virtual void GetName() {
                std::cout << "It's a bed!" << std::endl;
        };
};
 
class CCreator // Creator
{
public:
        virtual CProduct* CreateProduct() = 0;
};
 
template <class TheProduct>
class TCreator: public CCreator // ConcreteCreator. Створюємо підклас класу Creator з використанням шаблону,
                                 // для того щоб перевикористати ConcreteProduct.
                                 // Такий підхід запобігає створенню ConcreteCreator для кожного ConcreteProduct.
{
public:
        virtual CProduct* CreateProduct() {
                return new TheProduct;
        };
};
 
enum eProdacts
{
        table,
        chair,
        bed
};
 
// Приклад створення ConcreteProduct зі застосуванням шаблону ConcreteCreator (TCreator).
CProduct* CreateProdact(eProdacts e)
{
        CCreator* pCreator = NULL;
 
        switch (e)
        {
        case table: 
                pCreator = new TCreator<CTable>;
                break;
        case chair:
                pCreator = new TCreator<CChair>;
                break;
        case bed:
                pCreator = new TCreator<CBed>;
                break;
        default: return NULL;
        }
 
        return pCreator->CreateProduct();
}
 
int _tmain(int argc, _TCHAR* argv[])
{       
        CProduct* pConcreteProduct = NULL;
 
        pConcreteProduct = CreateProdact(chair);
 
        pConcreteProduct->GetName();
 
        return 0;
}

Джерела [ред.]

Література [ред.]

Алан Шаллоуей, Джеймс Р. Тротт Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М.: «Вильямс», 2002. — 288 с. — ISBN 0-201-71594-5