В предыдущем примере Design Pattern мы объяснили вкус шаблона Factory, который обычно используется в настоящее время. На этом занятии мы поймем более продвинутое решение, в котором было больше абстракции. Этот шаблон называется шаблоном проектирования Factory Method.
Определение: |
---|
Шаблон метода Factory предоставляет метод для создания объектов, но делегирует создание объекта подклассам. Шаблон проектирования метода фабрики решает эти проблемы аналогично шаблону фабрики с дополнительным уровнем абстракции. |
Объект может быть создан с использованием нового ключевого слова. Например, Объект A создает другой объект B, используя:
1
|
ClassB objB = new ClassB(); |
Таким образом, объект A содержит ссылку на объект B.
Поскольку объект A теперь зависит от объекта B, если последний будет модифицирован, нам придется перекомпилировать объект A. Ну, жизнь не так проста. Создание объекта может быть более сложным, и если будет больше связи, то обслуживание будет болезненной и дорогой работой при разработке программного обеспечения.
Чтобы избежать таких наихудших ситуаций, шаблоны спасательного проектирования приходят на помощь. Они пытаются создать слабую связь между клиентом и создателем объекта и дают разработчикам несколько других преимуществ в дизайне. Шаблон Factory Method является одним из таких шаблонов для решения проблем проектирования.
Общего пользования: |
---|
Шаблон проектирования фабричного метода обычно используется в различных средах, таких как Struts, Spring, Apache в сочетании с шаблоном проектирования декоратора. Существуют различные шаблоны J2EE, основанные на этом шаблоне Factory, например шаблон DAO. |
Давайте возьмем тот же пример швейной фабрики, где мы создавали разные типы одежды, но клиент не знал, как создаются эти продукты. Даже если бы нам пришлось добавить новый тип одежды, такой как куртка, код клиента не нужно менять, что повышает гибкость приложения.
Когда использовать шаблон метода фабрики?
- Создание объекта требует повторного использования кода без значительного дублирования кода.
- Класс не будет знать, какие подклассы потребуется создать.
- Подклассы могут указывать, какие объекты должны быть созданы.
- Родительские классы будут делегировать создание объектов своим подклассам.
Состав
На приведенной ниже диаграмме показана типичная структура шаблона Factory Method Design. В отличие от приведенного выше примера, здесь добавлен дополнительный класс Factory Abstract (Factory).
На приведенной выше схеме следующие участники:
- Продукт: это определяет интерфейс для объектов, которые создает фабричные методы.
- Конкретные продукты: реализует интерфейс продукта.
- Factory (Creator): это абстрактный класс, который определяет метод Factory, который возвращает объект продукта.
- Конкретная фабрика: этот класс реализует и переопределяет методы, которые были объявлены родительским классом фабрики.
Клиент (например, объект класса A) захочет использовать продукты, созданные классом ConcreteFactory (объект класса B). Однако в этом случае клиент содержит только ссылку на интерфейс B, а не объект «Class B», и поэтому ему не нужно ничего знать о classB. Фактически может быть несколько классов, которые могут реализовывать абстрактный класс.
Что означает шаблон фабричного метода, позволяет подклассам решать, какой класс создавать? |
По сути, это означает, что абстрактный класс Factory закодирован, не зная, какие именно классы ConcreteProduct будут созданы, т.е. будь то Trouser или Shirt. Это полностью определяется классом ConcreteFactory. |
Теперь давайте реализуем шаблон выше в нашем примере GarmentFactory.
Давайте сделаем некоторые руки сейчас. Мы не повторяем код для конкретных продуктов, таких как Shirt.java и Trouser.java, который можно найти в статье Factory Pattern .
Был создан новый абстрактный класс Factory, обращенный к клиенту.
1
2
3
|
public abstract class Factory { protected abstract GarmentType createGarments(String selection); } |
Класс GarmentFactory необходимо изменить, чтобы он наследовал абстрактный класс Factory.
01
02
03
04
05
06
07
08
09
10
|
public class GarmentFactory extends Factory{ public GarmentType createGarments(String selection) { if (selection.equalsIgnoreCase( 'Trouser' )) { return new Trouser(); } else if (selection.equalsIgnoreCase( 'Shirt' )) { return new Shirt(); } throw new IllegalArgumentException( 'Selection doesnot exist' ); } } |
Клиентский класс относится к классу Factory и классу метода createGarments (selection) Factory для создания продукта во время выполнения.
1
2
3
|
Factory factory = new GarmentFactory(); GarmentType objGarmentType = factory.createGarments(selection); System.out.println(objGarmentType.print()); |
Выгоды:
- Код является гибким, слабо связанным и пригодным для повторного использования, перемещая создание объекта из клиентского кода в класс Factory и его подклассы. Такой код легче поддерживать, поскольку создание возражений централизовано.
- Код клиента имеет дело только с интерфейсом Product, и, следовательно, любые конкретные продукты могут быть добавлены без изменения логики кода клиента.
- Преимущество фабричного метода состоит в том, что он может возвращать один и тот же экземпляр несколько раз или может возвращать подкласс, а не объект этого точного типа.
- Это поощряет последовательность в коде, поскольку объект создается посредством Фабрики, которая навязывает определенный набор правил, которым должен следовать каждый. Это позволяет избежать использования другого конструктора на другом клиенте.
Пример:
JDBC является хорошим примером для этого шаблона; Код приложения не должен знать, с какой базой данных он будет использоваться, поэтому он не знает, какие классы драйверов для конкретной базы данных он должен использовать. Вместо этого он использует фабричные методы, чтобы получить соединения, операторы и другие объекты для работы. Это дает гибкость для изменения внутренней базы данных без изменения уровня DAO.
Ниже приведены некоторые примеры из SDK:
Метод valueOf (), который возвращает созданный фабрикой объект, эквивалентный значению переданного параметра.
Метод getInstance (), который создает экземпляр класса Singleton.
Метод newInstance (), который используется для создания и возврата нового экземпляра из метода фабрики при каждом вызове.
Скачать образец кода
Ссылка: Разработка лучших практик с использованием Factory Method Pattern от нашего партнера JCG Майнака Госвами в блоге Idiotechie .