Сравнение фабрик
В этой статье мы попробуем разобраться чем отличаются:
- Фабрика
- Создающий метод
- Статический фабричный метод
- Простая фабрика
- Фабричный метод
- Абстрактная фабрика
Во многих книгах и источниках определения «фабрик» даётся авторами по-своему. Это создаёт большую путаницу при чтении материалов в интернете.
Итак, давайте разберёмся в вариациях фабрик, чтобы раз и навсегда понять разницу между ними.
1. Фабрика
Фабрика — это общая концепция проектирования функций, методов и классов, когда какая-то одна часть программы отвечает за создание других частей программы.
Вы можете услышать слово Фабрика от других людей, когда они имеют в виду:
- функцию или метод создающую все объекты программы;
- класс, создающий пользователей системы;
- статический метод, оборачивающий конструктор класса;
- один из классических фабричных паттернов, приведённых ниже.
То, что человек имеет в виду, произнося Фабрика, проще всего понять из контекста, мы сейчас рассмотрим все вариации.
2. Создающий метод
Создающий метод — это простой метод-обёртка над вызовом конструктора продукта. Выделив создающий метод, вы изолируете любые изменения в конструировании продуктов от основного кода. Например, вы можете вовсе убрать вызов конструктора из создающего метода, отдавая вместо нового какой-то существующий объект.
Многие называют его фабричным методом, только потому, что он создаёт новые объекты. Типичная логика: «этот метод создаёт объекты, а раз все фабрики создают что-то, значит этот метод — фабричный». И это вносит основную путаницу между понятием Создающего метода и паттерном Фабричный метод.
В этом примере, метод next
является создающим методом:
3. Статический фабричный метод
Статический фабричный метод — вариация создающего метода, объявленная как static
. Если этот метод создаёт объекты своего же класса, то, по сути, он выступает в роли альтернативного конструктора. Это может быть полезно, если:
-
Требуется создать разные по функциональности конструкторы, у которых бы совпадали сигнатуры (например,
Random(int max)
иRandom(int min)
). Это невозможно во многих языках программирования, но создав статический метод, вы можете обойти это ограничение. -
Хочется повторно использовать готовые объекты, вместо создания новых (например, паттерн Одиночка). При вызове конструктора вы всегда создаёте новый объект. Это можно обойти, если вынести вызов конструктора в новый метод. В этом методе вы можете сначала поискать готовый объект в каком-то кеше, и только если его нет, создать новый объект.
В следующем примере, метод load
является статическим фабричным методом — он предоставляет удобный способ загрузить пользователя из базы данных.
4. Паттерн Простая фабрика
Паттерн Простая фабрика — это класс, в котором есть один метод с большим условным оператором, выбирающим создаваемый продукт. Этот метод вызывают с неким параметром, по которому определяется какой из продуктов нужно создать. У простой фабрики, обычно, нет подклассов.
Обычно, простую фабрику путают с общим понятием Фабрики или с любым из фабричных паттернов.
Если объявить класс простой фабрики абстрактным (Java, C#), это не сделает его одним и тем же, что и абстрактная фабрика!
Вот пример простой фабрики:
Простая фабрика находится в шаге от того, чтобы стать Фабричным методом.
5. Паттерн Фабричный метод
Паттерн Фабричный метод — это устройство классов, при котором подклассы могут переопределять тип создаваемого в суперклассе продукта.
Если вы имеете иерархию продуктов и абстрактный создающий метод, который переопределяется в подклассах, то перед вами паттерн Фабричный метод.
6. Паттерн Абстрактная фабрика
Паттерн Абстрактная фабрика — это устройство классов, облегчающее создание семейств продуктов.
Что такое семейство продуктов? Например, классы Транспорт
+ Двигатель
+ Управление
. Вариациями этого семейства могут стать:
-
Автомобиль
+ДвигательВнутренннегоСгорания
+Руль
-
Самолет
+РеактивныйДвигатель
+Штурвал
Если у вас нет семейств продуктов, значит не может быть и абстрактной фабрики.
Многие путают паттерн абстрактная фабрика с классом простой фабрики, объявленным как abstract
, но это далеко не одно и то же!
Послесловие
Теперь, когда вы окончательно разобрались в терминологии, почитайте наши описания фабричных паттернов: