Builder Pattern β€” это ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ проСктирования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для пошагового создания слоТных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². Π­Ρ‚ΠΎΡ‚ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ особСнно ΠΏΠΎΠ»Π΅Π·Π΅Π½, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ мноТСство ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ ΠΈΠ»ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄Π΅Π»Π°ΡŽΡ‚ Π΅Π³ΠΎ созданиС Ρ‡Π΅Ρ€Π΅Π· конструкторы Π½Π΅ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌ.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ

  • Π Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ построСния ΠΈ прСдставлСния. Π‘ΠΈΠ»Π΄Π΅Ρ€ позволяСт ΠΎΡ‚Π΄Π΅Π»ΠΈΡ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎΡ‚ Π΅Π³ΠΎ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΉ структуры. Π­Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ чистым ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΌ.
  • Пошаговая сборка. ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΈΠ»ΠΈ части ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΏΡ€ΠΈ этом сам процСсс создания ΠΌΠΎΠΆΠ΅Ρ‚ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ нСзависимо ΠΎΡ‚ основной Π»ΠΎΠ³ΠΈΠΊΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
  • Π˜ΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ. ΠŸΠ°Ρ‚Ρ‚Π΅Ρ€Π½ Π±ΠΈΠ»Π΄Π΅Ρ€ часто примСняСтся для создания нСизмСняСмых ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². ПослС сборки ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΅Π³ΠΎ нСльзя ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠ°Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΡΠΊΠ°Π·ΡƒΠ΅ΠΌΠΎΡΡ‚ΡŒ ΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ примСнСния

Рассмотрим созданиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Car, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ настроСк, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ Ρ‚ΠΈΠΏ двигатСля, количСство Π΄Π²Π΅Ρ€Π΅ΠΉ, Ρ†Π²Π΅Ρ‚ ΠΈ Ρ‚.Π΄.

Π‘Π΅Π· использования ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° Β«Π‘ΠΈΠ»Π΄Π΅Ρ€Β» ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΡ‚ΡŒΡΡ с Ρ‚Π°ΠΊΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ: Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ конструкторы, Ρ‡Ρ‚ΠΎ ΡƒΡ…ΡƒΠ΄ΡˆΠ°Π΅Ρ‚ Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΡΡ‚ΡŒ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΊΠΎΠ΄Π°. ΠŸΠ°Ρ‚Ρ‚Π΅Ρ€Π½ Β«Π‘ΠΈΠ»Π΄Π΅Ρ€Β» ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ этого, ΠΏΡ€ΠΈ этом ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ fluent API ΡΡ‚ΠΈΠ»ΡŒ β€” ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±ΠΈΠ»Π΄Π΅Ρ€Π°, позволяя Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡ… Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠΎΠΉ. Π­Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΊΠΎΠ΄ Π±ΠΎΠ»Π΅Π΅ Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ Π»Π΅Π³ΠΊΠΈΠΌ для чтСния.

public class Car {
    private String engine;
    private int doors;
    private String color;
 
    private Car(CarBuilder builder) {
        this.engine = builder.engine;
        this.doors = builder.doors;
        this.color = builder.color;
    }
 
    public static class CarBuilder {
        private String engine;
        private int doors;
        private String color;
 
        public CarBuilder setEngine(String engine) {
            this.engine = engine;
            return this;
        }
 
        public CarBuilder setDoors(int doors) {
            this.doors = doors;
            return this;
        }
 
        public CarBuilder setColor(String color) {
            this.color = color;
            return this;
        }
 
        public Car build() {
            return new Car(this);
        }
    }
    
}

ИспользованиС ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π°:

Car car = new Car.CarBuilder()
    .setEngine("V8")
    .setDoors(4)
    .setColor("Red")
    .build();
 
System.out.println(car);

ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π°

  1. Чистый ΠΊΠΎΠ΄. ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² становится ясной ΠΈ понятной, Π΄Π°ΠΆΠ΅ Ссли Ρƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° мноТСство ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².
  2. Π“ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ Π² создании ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ². МоТно Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ сразу, Π° Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈΡ… ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ нСобходимости, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ процСсс сборки Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΈΠΌ.
  3. ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ нСизмСняСмыми послС создания, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² процСссС сборки.
  4. ΠœΠΈΠ½ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΎΠΊ конструкторов. Π­Ρ‚ΠΎ позволяСт ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ мноТСства конструкторов для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².

НСдостатки

  • УслоТнСниС ΠΊΠΎΠ΄Π°. Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ класса-Π±ΠΈΠ»Π΄Π΅Ρ€Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ объСм ΠΊΠΎΠ΄Π°, особСнно Ссли ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π½Π΅ Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ слоТСн, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π°Π²Π΄Π°Ρ‚ΡŒ использованиС ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π°.
  • ΠœΠ½ΠΎΠ³ΠΎΡΠ»ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ. Если ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², Ρ‚ΠΎ использованиС Π±ΠΈΠ»Π΄Π΅Ρ€Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ излишним ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½Π΅Π½ΡƒΠΆΠ½ΡƒΡŽ ΠΌΠ½ΠΎΠ³ΠΎΡΠ»ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ.

Когда ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ?

  • Когда ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠΌΠ΅Π΅Ρ‚ мноТСство ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².
  • Когда Π½ΡƒΠΆΠ΅Π½ Π³ΠΈΠ±ΠΊΠΈΠΉ процСсс создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒΡŽ пошагового добавлСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².
  • Когда ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ нСизмСняСмым, ΠΈ послС сборки Π΅Π³ΠΎ состояниС Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ.

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹ΠΉ Π±ΠΈΠ»Π΄Π΅Ρ€

ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля

Одной ΠΈΠ· распространСнных ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ являСтся отсутствиС явного указания Π½Π° ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΡ€ΠΈ использовании Π±ΠΈΠ»Π΄Π΅Ρ€Π°. Если ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠΌΠ΅Π΅Ρ‚ поля, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ для заполнСния (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΈΠ»ΠΈ имя), Π½ΠΎ ΠΈΡ… установка Π½Π΅ контролируСтся Π±ΠΈΠ»Π΄Π΅Ρ€ΠΎΠΌ, это ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ созданию Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Ρ… ΠΈΠ»ΠΈ Π½Π΅Π²Π°Π»ΠΈΠ΄Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

РСшСниС:

  • ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· конструктор Π±ΠΈΠ»Π΄Π΅Ρ€Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡ… ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ. ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Ρ†Π΅ΠΏΠΎΡ‡ΠΊΡƒ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ².

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

public class Car {
    private final String engine;  // ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
    private final String model;   // ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
    private int doors;            // ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
    private String color;         // ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
 
    // ΠŸΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΉ конструктор для сборки ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ‡Π΅Ρ€Π΅Π· Π±ΠΈΠ»Π΄Π΅Ρ€
    private Car(CarBuilder builder) {
        this.engine = builder.engine;
        this.model = builder.model;
        this.doors = builder.doors;
        this.color = builder.color;
    }
 
    // БтатичСский ΠΌΠ΅Ρ‚ΠΎΠ΄ для создания Π±ΠΈΠ»Π΄Π΅Ρ€Π° с ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ полями
    public static CarBuilder builder(String engine, String model) {
        return new CarBuilder(engine, model);
    }
 
    public static class CarBuilder {
        private final String engine;  // ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
        private final String model;   // ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
        private int doors = 4;        // Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
        private String color = "Black";  // Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
 
        // ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ Π±ΠΈΠ»Π΄Π΅Ρ€Π° с ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ полями
        public CarBuilder(String engine, String model) {
            if (engine == null || engine.isEmpty()) {
                throw new IllegalArgumentException("Engine is required");
            }
            if (model == null || model.isEmpty()) {
                throw new IllegalArgumentException("Model is required");
            }
            this.engine = engine;
            this.model = model;
        }
 
        // ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ для установки Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠΎΠ»Π΅ΠΉ
        public CarBuilder setDoors(int doors) {
            this.doors = doors;
            return this;
        }
 
        public CarBuilder setColor(String color) {
            this.color = color;
            return this;
        }
 
        // ΠœΠ΅Ρ‚ΠΎΠ΄ для сборки ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Car
        public Car build() {
            return new Car(this);
        }
    }
}

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ создании Π±ΠΈΠ»Π΄Π΅Ρ€Π°:

Car car = Car.builder("V8", "Sedan")  // ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠΎΠ»Π΅ΠΉ Ρ‡Π΅Ρ€Π΅Π· статичСский ΠΌΠ΅Ρ‚ΠΎΠ΄
    .setDoors(2)                      // ΠžΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ поля
    .setColor("Red")
    .build();

Валидация создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°

Π•Ρ‰Ρ‘ ΠΎΠ΄Π½Π° частая ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π²ΠΎ врСмя процСсса построСния Π½Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‚ΡΡ ограничСния Π½Π° ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΏΠΎΠ»Π΅ΠΉ. НапримСр, Π½Π΅ всСгда провСряСтся ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ Π»ΠΎΠ³ΠΈΠΊΠ° взаимодСйствия ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ созданию Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

РСшСниС:
ДобавляйтС Π² Π±ΠΈΠ»Π΄Π΅Ρ€ Π»ΠΎΠ³ΠΈΠΊΡƒ Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ состояния ΠΏΠ΅Ρ€Π΅Π΄ созданиСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π­Ρ‚ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ всС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ совмСстимы ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π΅Π½.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€:

public Car build() {
    if (doors < 2 || doors > 6) {
        throw new IllegalArgumentException("Invalid number of doors");
    }
    return new Car(this);
}

ΠœΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²

Когда ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π±ΠΈΠ»Π΄Π΅Ρ€Π° Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ нСсколько Ρ€Π°Π·, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡΡ‚Π°Ρ‚ΡŒΡΡ Π½Π΅Π·Π°ΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ нСпрСдсказуСмоС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ нас Π΅ΡΡ‚ΡŒ Π±ΠΈΠ»Π΄Π΅Ρ€ для создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Car, ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ для установки количСства Π΄Π²Π΅Ρ€Π΅ΠΉ (setDoors) Π±Ρ‹Π» Π²Ρ‹Π·Π²Π°Π½ Π΄Π²Π°ΠΆΠ΄Ρ‹:

Car car = new Car.CarBuilder("V8")
    .setDoors(4)
    .setDoors(2)  // Π­Ρ‚ΠΎΡ‚ Π²Ρ‹Π·ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡˆΠ΅Ρ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅
    .setColor("Red")
    .build();

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ car Π±ΡƒΠ΄Π΅Ρ‚ создан с двумя двСрями, хотя программист ΠΌΠΎΠ³ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ 4 Π΄Π²Π΅Ρ€ΠΈ (ΠΈΠ·-Π·Π° ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π°). Вакая ситуация особСнно распространСна, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ конфигурируСтся динамичСски, ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π΄Π° нСсколько Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ с Π±ΠΈΠ»Π΄Π΅Ρ€ΠΎΠΌ, Π½Π΅ зная всСх Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ.

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ Π½Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ². Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½Ρ‹Ρ… Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ, Π±Ρ‹Π» Π»ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΡƒΠΆΠ΅ Π²Ρ‹Π·Π²Π°Π½ Ρ€Π°Π½Π΅Π΅. Если ΠΌΠ΅Ρ‚ΠΎΠ΄ вызываСтся ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π±Ρ€ΠΎΡΠΈΡ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ².

public static class CarBuilder {
    private String engine;
    private int doors;
    private String color;
    private boolean doorsSet = false;  // Π€Π»Π°Π³, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ setDoors ΡƒΠΆΠ΅ Π±Ρ‹Π» Π²Ρ‹Π·Π²Π°Π½
 
    public CarBuilder(String engine) {
        this.engine = engine;
    }
 
    public CarBuilder setDoors(int doors) {
        if (doorsSet) {
            throw new IllegalStateException("Doors can only be set once");
        }
        this.doors = doors;
        doorsSet = true;
        return this;
    }
 
    public CarBuilder setColor(String color) {
        this.color = color;
        return this;
    }
 
    public Car build() {
        return new Car(this);
    }
}

Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ пСрСзаписи ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ². Если Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½Ρ‹Π΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², Π½ΠΎ ΠΏΡ€ΠΈ этом Π²Π°ΠΆΠ½ΠΎ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»ΠΎ Π²ΠΈΠ΄Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ пСрСзаписываСтся Π½ΠΎΠ²Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ.

public CarBuilder setDoors(int doors) {
    if (this.doors != 0) {
        System.out.println("Warning: Doors value is being overwritten from " + this.doors + " to " + doors);
    }
    this.doors = doors;
    return this;
}

ИспользованиС Fluent API Step building. ΠŸΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

public class Car {
    private final String engine;  // ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
    private final int doors;      // ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
    private final String color;   // ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΠΎΠ»Π΅
 
    // ΠŸΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΉ конструктор для сборки Ρ‡Π΅Ρ€Π΅Π· ΠΏΠΎΡˆΠ°Π³ΠΎΠ²ΡƒΡŽ сборку
    private Car(String engine, int doors, String color) {
        this.engine = engine;
        this.doors = doors;
        this.color = color;
    }
 
    // Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ для ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ шага: Π²Ρ‹Π±ΠΎΡ€ двигатСля
    public interface EngineStep {
        DoorsStep setEngine(String engine);
    }
 
    // Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ для Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ шага: Π²Ρ‹Π±ΠΎΡ€ Π΄Π²Π΅Ρ€Π΅ΠΉ
    public interface DoorsStep {
        ColorStep setDoors(int doors);
    }
 
    // Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ для Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅Π³ΠΎ шага: Π²Ρ‹Π±ΠΎΡ€ Ρ†Π²Π΅Ρ‚Π°
    public interface ColorStep {
        BuildStep setColor(String color);
    }
 
    // Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ для Ρ„ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ шага: Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ сборки
    public interface BuildStep {
        Car build();
    }
 
    // Класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΏΠΎΡˆΠ°Π³ΠΎΠ²ΡƒΡŽ сборку
    public static class Builder implements EngineStep, DoorsStep, ColorStep, BuildStep {
        private String engine;
        private int doors;
        private String color;
 
        @Override
        public DoorsStep setEngine(String engine) {
            this.engine = engine;
            return this;
        }
 
        @Override
        public ColorStep setDoors(int doors) {
            this.doors = doors;
            return this;
        }
 
        @Override
        public BuildStep setColor(String color) {
            this.color = color;
            return this;
        }
 
        @Override
        public Car build() {
            return new Car(engine, doors, color);
        }
    }
 
    // ΠœΠ΅Ρ‚ΠΎΠ΄ для запуска пошаговой сборки
    public static EngineStep builder() {
        return new Builder();
    }
}

ΠœΠ΅Ρ‚Π° информация

ΠžΠ±Π»Π°ΡΡ‚ΡŒ:: 00 Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°
Π ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ:: ΠŸΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ проСктирования
Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ::
Π‘ΠΎΠ·Π΄Π°Π½Π°:: 2024-10-04
Автор::

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹

Π”ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ Π·Π°ΠΌΠ΅Ρ‚ΠΊΠΈ