- Фабричный метод
-
Фабричный метод (англ. Factory Method) — порождающий шаблон проектирования, предоставляющий подклассам интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс инстанциировать. Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами на более высоком уровне. Также известен под названием виртуальный конструктор.
Содержание
Цель
Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанциировать. Фабричный метод позволяет классу делегировать создание подклассам. Используется, когда:
- классу заранее неизвестно, объекты каких подклассов ему нужно создавать.
- класс спроектирован так, чтобы объекты, которые он создаёт, специфицировались подклассами.
- класс делегирует свои обязанности одному из нескольких вспомогательных подклассов, и планируется локализовать знание о том, какой класс принимает эти обязанности на себя.
Структура
- Product - продукт
- определяет интерфейс объектов, создаваемых абстрактным методом;
- ConcreteProduct - конкретный продукт
- реализует интерфейс Product;
- Creator - создатель
- объявляет фабричный метод, который возвращает объект типа Product. Может также содержать реализацию этого метода "по умолчанию";
- может вызывать фабричный метод для создания объекта типа Product;
- ConcreteCreator - конкретный создатель
- переопределяет фабричный метод таким образом, чтобы он создавал и возвращал объект класса ConcreteProduct.
Плюсы
- позволяет сделать код создания объектов более универсальным, не привязываясь к конкретным классам (ConcreteProduct), а оперируя лишь общим интерфейсом (Product);
- позволяет установить связь между параллельными иерархиями классов.
Минусы
- необходимость создавать наследника Creator для каждого нового типа продукта (ConcreteProduct).
Примеры
public class FactoryMethodExample { public static void main(String[] args) { // an array of creators Creator[] creators = new Creator[2]; creators[0] = new ConcreteCreatorA(); creators[1] = new ConcreteCreatorB(); // iterate over creators and create products for (Creator creator: creators) { Product product = creator.factoryMethod(); System.out.printf("Created {%s}\n", product.getClass()); } } } // Product abstract class Product { } // ConcreteProductA class ConcreteProductA extends Product { } // ConcreteProductB class ConcreteProductB extends Product { } // Creator abstract class Creator { public abstract Product factoryMethod(); } // У этого класса может быть любое кол-во наследников. // Для создания нужного нам объекта можно написать следующие Фабрики: ConcreteCreatorA, ConcreteCreatorB // ConcreteCreatorA class ConcreteCreatorA extends Creator { @Override public Product factoryMethod() { return new ConcreteProductA(); } } // ConcreteCreatorB class ConcreteCreatorB extends Creator { @Override public Product factoryMethod() { return new ConcreteProductB(); } }
Результат работы:
Created {class ConcreteProductA}
Created {class ConcreteProductB}
C++
#include<iostream> #include<string> using namespace std; // "Product" class Product{ public: virtual string getName() = 0; }; // "ConcreteProductA" class ConcreteProductA : public Product{ public: string getName(){ return "ConcreteProductA"; } }; // "ConcreteProductB" class ConcreteProductB : public Product{ public: string getName(){ return "ConcreteProductB"; } }; // "Creator" class Creator{ public: virtual Product* FactoryMethod() = 0; }; // "ConcreteCreatorA" class ConcreteCreatorA : public Creator{ public: Product* FactoryMethod() { return new ConcreteProductA(); } }; // "ConcreteCreatorB" class ConcreteCreatorB : public Creator{ public: Product* FactoryMethod() { return new ConcreteProductB(); } }; int main(){ const int size = 2; // An array of creators Creator* creators[size]; creators[0] = new ConcreteCreatorA(); creators[1] = new ConcreteCreatorB(); // Iterate over creators and create products for(int i=0;i<size;i++){ Product* product = creators[i]->FactoryMethod(); cout<<product->getName()<<endl; delete product; } int a; cin>>a; for(int i=0;i<size;i++){ delete creators[i]; } return 0; }
C#
// Factory Method pattern -- Structural example class MainApp { static void Main() { // An array of creators Creator[] creators = new Creator[2]; creators[0] = new ConcreteCreatorA(); creators[1] = new ConcreteCreatorB(); // Iterate over creators and create products foreach(Creator creator in creators) { Product product = creator.FactoryMethod(); Console.WriteLine("Created {0}", product.GetType().Name); } // Wait for user Console.Read(); } } // "Product" abstract class Product { } // "ConcreteProductA" class ConcreteProductA : Product { } // "ConcreteProductB" class ConcreteProductB : Product { } // "Creator" abstract class Creator { public abstract Product FactoryMethod(); } // "ConcreteCreatorA" class ConcreteCreatorA : Creator { public override Product FactoryMethod() { return new ConcreteProductA(); } } // "ConcreteCreatorB" class ConcreteCreatorB : Creator { public override Product FactoryMethod() { return new ConcreteProductB(); } }