Фабричный метод (англ. Factory Method) — порождающий паттерн (шаблон) проектирования, предоставляющий подклассаминтерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какойкласс создавать. Иными словами, Фабрика делегирует создание объектов наследникам родительского класса. Этопозволяет использовать в коде программы не специфические классы, а манипулировать абстрактными объектами наболее высоком уровне. Также известен под названием виртуальный конструктор (англ. Virtual Constructor).
Цель
Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой классинстанциировать. Фабричный метод позволяет классу делегировать создание подклассов. Используется, когда:
- классу заранее неизвестно, объекты каких подклассов ему нужно создавать.
- класс спроектирован так, чтобы объекты, которые он создаёт, специфицировались подклассами.
- класс делегирует свои обязанности одному из нескольких вспомогательных подклассов, и планируетсялокализовать знание о том, какой класс принимает эти обязанности на себя.
Плюсы
- позволяет сделать код создания объектов более универсальным, не привязываясь к конкретным классам(ConcreteProduct), а оперируя лишь общим интерфейсом (Product);
- позволяет установить связь между параллельными иерархиями классов.
Минусы
- необходимость создавать наследника Creator для каждого нового типа продукта (ConcreteProduct).
- Product — продукт
- определяет интерфейс объектов, создаваемых абстрактным методом;
- ProductA, ProductB — конкретный продукт
- реализует интерфейс Product;
- FactoryAbstract — создатель
- объявляет фабричный метод, который возвращает объект типа Product. Может также содержатьреализацию этого метода «по умолчанию»;
- может вызывать фабричный метод для создания объекта типа Product;
- Factory — конкретный создатель
- переопределяет фабричный метод таким образом, чтобы он создавал и возвращал объект классаConcreteProduct.
1: <?php
2:
3: abstract class Product
4: {
5: }
6:
7: class ProductA extends Product
8: {
9: }
10:
11: class ProductB extends Product
12: {
13: }
14:
15: abstract class FactoryAbstract
16: {
17: public function create($type)
18: {
19: switch ($type) {
20: case'A':
21: return new ProductA();
22: case'B':
23: default:
24: return new ProductB();
25: }
26: }
27: }
28:
29: class Factory extends FactoryAbstract
30: {
31: }
32:
33: $factory = new Factory();
34: $productA = $factory->create('A');