Зачем нужно return this, внутри класса Builder, в шаблоне Builder

132
22 ноября 2019, 20:00
public class BuilderLesson {
    public static void main(String[] args) {
        Car lada = new Car.Builder("Лада").setColour("Белый").setMinSpeed(0).build();
        lada.getColour();
        lada.getMinSpeed();
    }
}
class Car {
    private String name;
    private String colour = "Black";
    private int maxSpeed = 250;
    private int minSpeed;
    public String getName() {
        return name;
    }
    public String getColour() {
        return colour;
    }
    public int getMaxSpeed() {
        return maxSpeed;
    }
    public int getMinSpeed() {
        return minSpeed;
    }
    private Car(Builder builder) {
        this.name = builder.name;
        this.colour = builder.colour;
        this.maxSpeed = builder.maxSpeed;
        this.minSpeed = builder.minSpeed;
    }
    static class Builder {
        private String name;
        private String colour = "Black";
        private int maxSpeed = 250;
        private int minSpeed;
        public Builder(String name) {
            this.name = name;
        }
        public Builder setColour(String colour) {
            this.colour = colour;
            return this; // Для чего тут
        }
        public Builder setMaxSpeed(int maxSpeed) {
            this.maxSpeed = maxSpeed;
            return this; // Тут
        }
        public Builder setMinSpeed(int minSpeed) {
            this.minSpeed = minSpeed;
            return this; // И тут, возвращать this
        }
        public Car build() {
            return new Car(this);
        }
    }
}
Answer 1

У вас применен шаблон Builder и шаблон Fluent Interface.

Fluent Interface - это интерфейс который предоставляет цепочки методов(как стримы). Он состоит из двух типов методов: cascade method и chaining method.

Cascade method: что-то делает с this, возвращает this;

Chaining method: что-то делает с новым объектом созданным с помощью this, возвращает новый объект.

Сделано это для улучшения читаемости и упрощения кода.

Пример без шаблона:

A a = new A(...);
a.setName(...);
a.setAge(...);
a.setColor(...);
    ...

Пример с шаблоном Fluent Interface(без Builder):

A a = new A(...);
a.setName(...).setAge(...).setColor(...)...

Сделать такую цепочку методов можно из-за того что каждый метод используется с объектом A, и каждый метод возвращает объект A.

Т.е., примерно так: a.setName(...){тут возвращаем a}.setAge(...){тут возвращаем a}.setColor(...){тут возвращаем a}...

Пример с библиотекой Stream API:

list = list.stream()
         .map(x -> x/2)
         .filter(x -> x % 3 == 3)
         .collect(Collector.toList());
Answer 2

this возвращается для реализации цепочки вызова методов (method chaining), чтобы следующий метод в цепочке вызовов мог обратиться к тому же объекту (this - это ссылка на текущий объект) и не требовалось каждый раз обращаться к первоначально созданному:

obj.method1().method2();

вместо

obj.method1(); 
obj.method2();

при обработке строки из первого примера в классе obj будет вызван method1(), который результатом своей работы через this вернет этот же объект obj, то есть, после выполнения метода часть obj.method1() будет как бы заменена на obj и для него уже будет вызван method2() и так далее для всей цепочки объект будет передаваться от метода к методу через this, который эти методы возвращают.

READ ALSO
Не получается использовать Alarm Manager для повторения вызова функции

Не получается использовать Alarm Manager для повторения вызова функции

Хочу использовать AlarmManager, для того, чтобы приложение делало определенные действия в полночь (запись в бд), но не могу сконструировать простое...

122
Как вернуть несколько изображений Java

Как вернуть несколько изображений Java

Пишу маленькое REST приложениеЕсть метод в контроллере

126
Как я могу анимировать bar charts используя clip-path?

Как я могу анимировать bar charts используя clip-path?

У меня есть bar chart, на элементах которого используется градиентный фон

136
Экспортировать историю Skype 8

Экспортировать историю Skype 8

Хочу собрать историю с 8го скайпа, пока не стало слишком поздно - встречается информация (не пойму, насколько достоверная), что она хранится...

165