Шаблон проектирования строителя
Шаблон проектирования Builder — это классический шаблон проектирования Gang of Four Creation. В отличие от паттерна Pattern Design, Builder Design Pattern решает проблемы с созданием объектов из-за сложных конструкторов.
Существуют сценарии, когда класс состоит из слишком большого количества параметров, которые могут запутать понимание, в основном, когда все они имеют общий тип данных. В основном конструктор создается с использованием всех параметров класса, включая те, которые являются необязательными или редко используются.
При создании объектов такого класса нам необходимо ознакомиться с документацией по классу, чтобы понять порядок параметра и необходимость отправки null в случае необязательного параметра.
Другой вариант — создать несколько конструкторов с необходимыми параметрами. Но этот подход не является действительно масштабируемым, когда задействовано много параметров. Шаблон проектирования Builder также очень полезен при создании неизменяемого объекта.
Шаблон Builder решает проблему с большим количеством необязательных параметров и несогласованным состоянием, предоставляя способ пошагового построения объекта и предоставляя метод, который фактически возвращает окончательный объект. Процесс создания объекта является общим, поэтому его можно использовать для создания различных представлений одного и того же объекта.
Шаблон проектирования построителя использует цепочку методов для реализации методов построителя.
Связывание методов используется для вызова нескольких методов для одного и того же объекта, который выполняется как один оператор. Цепочка методов реализована рядом методов, которые возвращают ссылку this для экземпляра класса.
Поскольку возвращаемые значения методов в цепочке являются этой ссылкой, эта реализация позволяет нам вызывать методы в цепочке, вызывая следующий метод для возвращаемого значения предыдущего метода в цепочке.
Это руководство является частью серии Creational Design Pattern. Взгляните на другие шаблоны креативного дизайна:
- Singleton Creational Design Pattern Java: объяснение [6 примеров кода]
- Factory Design Pattern Java Simplified [Простой пример из реальной жизни]
- Простые подробные примеры фабричного метода проектирования Java
- Пример абстрактного фабричного проектирования Java в реальном мире
- Реальный пример шаблона проектирования Builder на Java
- Прототип шаблона проектирования Java, пример реального мира
Когда использовать шаблон проектирования Builder?
- Шаблон Builder следует использовать всякий раз, когда задействован сложный конструктор.
- Когда Object нужно мне сделать в шагах.
- Когда нам нужно создать неизменяемый класс.
- Когда нам нужно создать объект с несколькими необязательными параметрами.
Реализация шаблона проектирования Builder
- Создайте внешний класс только с аргументами. Нет необходимости создавать какие-либо общедоступные конструкторы и методы установки/получения.
- Создайте статический вложенный класс, а затем скопируйте все аргументы из внешнего класса в класс Builder. Мы должны следовать соглашению об именах, и если имя класса — Student, то класс строителя должен называться StudentBuilder.
- Класс Builder должен иметь общедоступный конструктор со всеми обязательными/обязательными атрибутами в качестве параметров.
Класс Builder должен иметь методы для установки необязательных параметров, и он должен возвращать тот же объект Builder после установки необязательного атрибута. - Последним шагом является предоставление метода build() в классе построителя, который будет возвращать объект внешнего класса, необходимый клиентской программе. Для этого нам нужен частный конструктор во внешнем классе с объектом класса Builder в качестве аргумента.
Пример шаблона проектирования Builder в реальном мире
Рассмотрим сценарий, в котором у клиента есть сертификационный веб-сайт, и он хочет запросить у студентов их личную информацию. Студенту предоставляется форма с несколькими вопросами, из которых обязательными являются только имя и фамилия.
Клиент хочет сохранить эту информацию в неизменном объекте. Мы можем сохранить эту информацию, напрямую вызвав конструктор, но в форме достаточно вопросов, и студент может выбрать ответ только на некоторые из них.
Нецелесообразно создавать конструктор с различными комбинациями. Это идеальный сценарий для использования шаблона проектирования Builder.
Класс продукта
Класс Student
— это наш класс продукта, и он имеет статический внутренний класс StudentBuilder
.
package com.adevguide.java.designpatterns.builder; public class Student { private String firstName; // mandatory private String lastName; // mandatory private String age; // optional private String gender; // optional private boolean isGraduate; // optional private boolean hasExperience; // optional private String city; // optional private String state; // optional private boolean isEarning; // optional private Student(StudentBuilder builder) { this.firstName = builder.firstName; this.lastName = builder.lastName; this.age = builder.age; this.gender = builder.gender; this.isGraduate = builder.isGraduate; this.hasExperience = builder.hasExperience; this.city = builder.city; this.state = builder.state; this.isEarning = builder.isEarning; } @Override public String toString() { return " firstName=" + firstName + "\n lastName=" + lastName + "\n age=" + age + "\n gender=" + gender + "\n isGraduate=" + isGraduate + "\n hasExperience=" + hasExperience + "\n city=" + city + "\n state=" + state + "\n isEarning=" + isEarning; } public static class StudentBuilder { private String firstName; private String lastName; private String age; private String gender; private boolean isGraduate; private boolean hasExperience; private String city; private String state; private boolean isEarning; public StudentBuilder(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public StudentBuilder addAge(String age) { this.age = age; return this; } public StudentBuilder addGender(String gender) { this.gender = gender; return this; } public StudentBuilder addisGraduate(boolean isGraduate) { this.isGraduate = isGraduate; return this; } public StudentBuilder addHasExperience(boolean hasExperience) { this.hasExperience = hasExperience; return this; } public StudentBuilder addCity(String city) { this.city = city; return this; } public StudentBuilder addState(String state) { this.state = state; return this; } public StudentBuilder addIsEarning(boolean isEarning) { this.isEarning = isEarning; return this; } public Student build() { return new Student(this); } } }
Внешний класс Student
имеет один частный конструктор Student(StudentBuilder builder)
, который принимает объект построителя, а затем инициализирует параметры класса.
Статический внутренний класс StudentBuilder
имеет один общедоступный конструктор с обязательными параметрами в качестве аргументов. Это не обязательно, мы всегда можем создать конструктор без аргументов и передавать обязательные параметры через метод в качестве необязательных параметров.
Статический внутренний класс имеет отдельные методы для каждого из необязательных параметров, которые будут устанавливать значение параметра в объекте и возвращать экземпляр объекта.
Наконец, требуется общедоступный метод build()
, он вызовет частный конструктор внешнего класса, передаст ему экземпляр класса-строителя и вернет экземпляр внешнего класса.
Класс клиента
package com.adevguide.java.designpatterns.builder; /** * @author PraBhu * */ public class Client { public static void main(String[] args) { Student student = new Student.StudentBuilder("Pra", "Bhu") // mandatory parameters .addAge("25") // optional .addGender("M") // optional .addHasExperience(true) // optional .build(); // to get back student option System.out.println(student); } }
firstName=Pra
lastName=Bhu
age=25
gender=M
isGraduate=false
hasExperience=true
city=null
state=null
isEarning=false
Преимущества дизайна Builder Pattern
- Он обеспечивает четкое разделение между построением и представлением объекта.
- неизменность принудительно применяется к объекту после его создания.
- Код создания объекта менее подвержен ошибкам, поскольку пользователь будет знать, что он передает, благодаря явному вызову метода.
- Шаблон Builder повышает надежность, так как клиенту будет доступен только полностью построенный объект.
Подводные камни шаблона проектирования Builder
- Шаблон Builder многословен и требует дублирования кода, поскольку Builder должен скопировать все поля из исходного/внешнего класса.
Пример шаблона проектирования Builder
- java.lang.StringBuilder#append()
- java.nio.ByteBuffer#put() (также в CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer и DoubleBuffer)
- java.lang.StringBuffer#append()
- javax.swing.GroupLayout.Group#addComponent()
Исходный код шаблона проектирования Builder
Исходный код, использованный в этом руководстве, можно найти на GitHub.
использованная литература
https://medium.com/@ajinkyabadve/builder-design-patterns-in-java-1ffb12648850
Первоначально опубликовано на https://www.adevguide.com 3 сентября 2019 г.