Паттерн постепенного создания конструктора
Как статические фабричные методы, так и конструкторы плохо справляются с большим количеством параметров. Например, если у класса 6 полей, и мы хотим создать конструкторы для 2, 3 и т.д. параметров, то мы можем использовать паттерн постепенного создания конструктора, как показано ниже.
Однако даже этот подход становится сложным при большом количестве параметров. При чтении кода становится сложно понять, что означает каждый параметр, а также есть риск перепутать параметры одного типа и передать неверные значения.
Паттерн JavaBeans
Паттерн JavaBeans создает объект с помощью конструктора без параметров, а затем устанавливает значения параметров с помощью методов-setter.
Паттерн JavaBeans позволяет избежать путаницы при передаче большого количества параметров. Однако для создания объекта требуется вызов нескольких методов-setter, и до завершения процесса создания объекта может нарушаться его целостность. Из-за этого класс не может быть неизменным.
Паттерн Строитель
Чаще всего используется паттерн Строитель, который сочетает в себе надежность паттерна постепенного создания конструктора и удобочитаемость паттерна JavaBeans.
Вместо непосредственного создания объекта клиент вызывает конструктор с обязательными параметрами для получения объекта-строителя. Затем, используя методы-setter, которые предоставляет объект-строитель, клиент устанавливает желаемые значения необязательных параметров. Наконец, вызов метода build() без параметров возвращает необходимый объект.
Конструктор класса Builder принимает только обязательные параметры, а остальные необязательные параметры устанавливаются с помощью методов-setter. И, наконец, метод build() создает завершенный объект NutritionFactsWithBuilderPattern. Класс NutritionFactsWithBuilderPattern неизменяемый, а методы-setter класса Builder возвращают сам Builder, поэтому их можно вызывать в цепочке. Такой подход называется плавным API или связыванием методов.
С точки зрения клиента, паттерн Строитель позволяет писать и читать код проще.
Паттерн Строитель хорошо сочетается с иерархически структурированными классами
Класс Pizza.Builder — это обобщенный тип с рекурсивным ограничением типа, который использует абстрактный метод self() для поддержки связывания методов без приведения типов в дочерних классах. В дочерних классах этот абстрактный метод должен возвращать сам себя.
Теперь рассмотрим дочерние классы Pizza — нью-йоркскую пиццу и кальцоне, чтобы продемонстрировать гибкость паттерна Строитель.
Метод build() в каждом дочернем классе строителя возвращает конкретный дочерний класс. Способность метода в дочернем классе возвращать тип, являющийся подтипом типа, возвращаемого методом в базовом классе, называется ковариантным типом возвращаемого значения. Благодаря этой функции клиенту не нужно выполнять приведение типов.
Клиент может использовать перечисления Pizza и каждого дочернего класса, а также соответствующие методы для создания объектов.
Недостатки паттерна Строитель
- Необходимо создавать объект-строитель.
- Код может быть громоздким.
Заключение
Если конструктор или статический фабричный метод должен обрабатывать большое количество параметров, стоит рассмотреть паттерн Строитель.
Источники
- Эффективная Java
Комментарии0