Креативные шаблоны проектирования: шаблон "Строитель"

Возможно, вы уже знали о шаблонах проектирования, которые встречаются при изучении концепций программирования. Шаблоны проектирования всегда облегчают нашу жизнь и помогают очень удобно структурировать код. Среди трех основных типов шаблонов проектирования, известных как Творческий, Структурный и Поведенческий, мы находим Шаблон проектирования Строитель. по творческим шаблонам.

Использование шаблона проектирования Builder

Это созидательный шаблон. Это означает, что мы можем использовать это, когда создание объектов завершено. Итак, представьте, что мы хотим создавать объекты на одном и том же объекте разными способами. Например, мне нужно создать объект Employee только с имя и адрес электронной почты в качестве свойств. Но кто-то другой должен создать объект с именем, адресом электронной почты, возрастом и адресом сотрудника. В этом случае, что мы делаем традиционным способом?

Создавайте различные конструкторы, поддерживающие сценарии, известные как перенасыщение конструктора!

Традиционный код пути выглядит так:

public class Employee {
    String name;
    String email;
    int age;
    String address;
    String designation;
    List<String> qualifications;

    public Employee(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public Employee(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }

    public Employee(String name, String email, int age, String address) {
        this.name = name;
        this.email = email;
        this.age = age;
        this.address = address;
    }

    public Employee(String name, String email, int age, String address, String designation) {
        this.name = name;
        this.email = email;
        this.age = age;
        this.address = address;
        this.designation = designation;
    }

    public Employee(String name, String email, int age, String address, String designation, List<String> qualifications) {
        this.name = name;
        this.email = email;
        this.age = age;
        this.address = address;
        this.designation = designation;
        this.qualifications = qualifications;
    }
}

А в клиенте создаем объекты как хотим:

Employee e1 = new Employee("salitha", "[email protected]");
Employee e2 = new Employee("salitha", "[email protected]", 28);
Employee e3 = new Employee("salitha", "[email protected]", 28, "Horana");
Employee e4 = new Employee("salitha", "[email protected]", 28, "Horana", "SE");
Employee e5 = new Employee("salitha", "[email protected]", 28, "Horana", "SE", Arrays.asList("CMJD"));

В чем тогда проблема?

Я согласен с тем, что перекрашивание конструктора является приемлемым программным способом. Но давайте поймем настоящую проблему.

Что произойдет, если:

  • Сотрудник имеет так много свойств? Как определить столько конструкторов? Так много геттеров и сеттеров? Один и тот же код будет повторяться и класс станет слишком длинным.
  • Сотруднику не нужны некоторые свойства как обязательные? Даже если мы определим конструкторы, может появиться новое требование создать объект другим способом. Тогда как сделать свойства необязательными?

Давайте применим шаблон Builder!

Применить шаблон построителя

Здесь нужно выполнить несколько шагов.

  1. Создайте вложенный класс static для Builder.
  2. Создайте открытый конструктор с необходимыми параметрами внутри класса построителя.
  3. Скопируйте свойства в класс построителя и сделайте закрытыми только необходимые параметры и назначьте их внутри конструктора.
  4. Сделайте все параметры закрытыми final в классе main и назначьте их внутри конструктора
  5. Удалить сеттеры из основного класса
  6. Создайте общедоступные сеттеры для необязательных параметров, которые возвращают построитель
  7. Создайте общедоступный метод сборки, возвращающий экземпляр основного класса.

Возьмем класс Employee.

import java.util.List;

public class Employee {
    private final String name;
    private final String email;
    private final int age;
    private final String address;
    private final String designation;
    private final List<String> qualifications;

    public Employee(Employee.EmployeeBuilder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.age = builder.age;
        this.address = builder.address;
        this.designation = builder.designation;
        this.qualifications = builder.qualifications;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

    public String getDesignation() {
        return designation;
    }

    public List<String> getQualifications() {
        return qualifications;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", designation='" + designation + '\'' +
                ", qualifications=" + qualifications +
                '}';
    }

    public static class EmployeeBuilder {
        private final String name;
        private final String email;
        private int age;
        private String address;
        private String designation;
        private List<String> qualifications;

        public EmployeeBuilder(String name, String email) {
            this.name = name;
            this.email = email;
        }

        public EmployeeBuilder age(int age) {
            this.age = age;
            return this;
        }

        public EmployeeBuilder address(String address) {
            this.address = address;
            return this;
        }

        public EmployeeBuilder designation(String designation) {
            this.designation = designation;
            return this;
        }

        public EmployeeBuilder qualifications(List<String> qualifications) {
            this.qualifications = qualifications;
            return this;
        }

        public Employee build() {
            return new Employee(this);
        }
    }

Теперь мы готовы создавать объекты по своему усмотрению с неограниченной гибкостью!

Но вот теперь у нас нет суетливых конструкторов!!!

// with only required parameters
Employee e1 = new Employee.EmployeeBuilder("salitha", "[email protected]")
        .build();
// with required and optional parameters
Employee e2 = new Employee.EmployeeBuilder("salitha", "[email protected]")
        .age(28).build();
Employee e3 = new Employee.EmployeeBuilder("salitha", "[email protected]")
        .age(28).designation("SE").build();
// with all parameters
Employee e4 = new Employee.EmployeeBuilder("salitha", "[email protected]")
 .age(28)
.designation("SE")
.qualifications(Collections.singletonList("CMJD"))
.build();

Теперь вы видите, насколько гибкий наш Сотрудник…

Вот как мы реализуем шаблон проектирования Builder с нуля, используя Java.

Легкий путь для строителя

Вы можете просто использовать библиотеку Lombok для реализации своих POJO. Тогда Builder будет доступен с простой аннотацией под названием @Builder, которую мы поместили в класс! Как это сделать, вы можете прочитать в конце этой статьи: https://medium.com/@salithachathuranga94/pojos-in-java-with-lombok-307944323b8

После добавления Lombok наш класс станет более коротким и приятным. Это будет так. Вы должны попробовать эту замечательную библиотеку!

import lombok.*;

import lombok.*;

import java.util.List;

@Builder
@Getter
@Setter
@ToString
public class Employee {
String name;
    String email;
    int age;
    String address;
    String designation;
    List<String> qualifications;
}

Это все о шаблонах Builder, ребята!

До свидания!!!