Возвращение 'this' в сеттерах Java: плюсы, минусы, обсуждение
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Применение концепции Fluent Interface, когда сеттеры возвращают this
, позволяет организовать цепочку вызовов методов. Этот подход облегчает конфигурирование объектов путем компоновки вызовов методов.
Пример из реальной практики:
public class FluentWidget {
private int size;
private String color;
// Сеттеры возвращают "this" для организации цепочки вызовов
public FluentWidget setSize(int size) {
this.size = size;
return this;
}
public FluentWidget setColor(String color) {
this.color = color;
return this;
}
}
// Пример использования: FluentWidget widget = new FluentWidget().setSize(42).setColor("blue");
Такой подход делает код более консолидированным и кратким, но он отделяется от стандартной концепции void
сеттеров в Java Beans. Важно применять данный паттерн аккуратно, следя за целостностью кодовой базы.
Применение Fluent Interface к неизменяющимся объектам
В случае с неизменяемыми объектами используются методы в формате withX
, благодаря которым поддерживается целостность данных, не утрачивая данного свойства интерфейса.
public class ImmutableWidget {
private final int size;
private final String color;
public ImmutableWidget(int size, String color) {
this.size = size;
this.color = color;
}
// Методы c "with" для поддержки неизменяемости объектов
public ImmutableWidget withSize(int newSize) {
return new ImmutableWidget(newSize, this.color);
}
public ImmutableWidget withColor(String newColor) {
return new ImmutableWidget(this.size, newColor);
}
}
// Пример использования: ImmutableWidget widget = new ImmutableWidget(32, "red").withSize(42).withColor("blue");
Паттерн "Строитель"
Паттерн "Строитель" дополняет концепцию цепочек методов и облегчает создание сложных объектов, избавляя от необходимости использовать громоздкий конструктор.
public class WidgetBuilder {
private int size;
private String color;
// Методы строителя для настройки свойств
public WidgetBuilder setSize(int size) {
this.size = size;
return this;
}
public WidgetBuilder setColor(String color) {
this.color = color;
return this;
}
public FluentWidget build() {
return new FluentWidget(size, color);
}
}
// Пример использования: FluentWidget widget = new WidgetBuilder().setSize(42).setColor("blue").build();
Для уточнения назначения сеттеров в цепи вызовов их можно именовать, следуя шаблону chainSetXyz
.
Влияние на среду разработки и работу в команде
Учитывайте инструменты и библиотеки, которые могут не поддерживать нетипичные подходы к работе со сеттерами.
На счет работы в команде, мнения программистов разнятся: некоторые находят цепочку вызовов "ужасной", в то время как другие видят в ней ключ к более эффективному коду. Важно знать предпочтения вашей команды с целью поддержания высокого качества кода.
Визуализация
Ваш метод в Java можно представить как скоростной поезд на рельсах:
Традиционный сеттер: Цепочной сеттер:
🚂 Установить скорость -> 🛤 🚂 Установить скорость -> 🛤 -> 🚋 Добавить вызов -> 🛤
| ↘️
🛑 Остановиться 🚂 Продолжить движение
В традиционном сеттере поезд (метод) останавливается после каждого действия. С цепочкой сеттеров поезд присоединяет дополнительные вагоны (this
) и продолжает движение.
public MyClass setSpeed(int speed) {
this.speed = speed;
// Поезд присоединил новый вагон. Вперед!
return this;
}
Избавляемся от монструозных конструкторов
Длинные конструкторы с большим количеством параметров часто являются причиной ошибок и сложны для чтения. Использование this
в сеттерах или паттерна Строитель страхует от этого.
Заметка для архитектора: Управление архитектурой кода
Будьте внимательны, чтобы не нарушить принцип единой ответственности (SRP), поскольку методы начинают выполнять больше функций, чем предусматривалось изначально. Также следует учесть возможное влияние на оптимизацию JVM.
Обратный поворот: изменения в возвращаемом типе
Изменение возвращаемого типа сеттеров в будущем может ограничить гибкость цепочек вызовов. Проектируйте API так, чтобы они были устойчивы к будущим изменениям.
Альтернативы: Фабричные и статические методы
Фабричные и статические методы предлагают альтернативные пути создания объектов, которые не требуют использования громоздких конструкторов или сложных Fluent Interface.
Полезные материалы
- Fluent Interface by Martin Fowler — ознакомьтесь с паттерном Fluent Interface от его создателя.
- Effective Java, 3rd Edition — в этой книге собраны лучшие практики Java и шаблоны проектирования.
- How to achieve method chaining in Java? – Stack Overflow — мнения и опыт сообщества на тему цепочек методов и их практического применения.
- JavaBeans Specification — официальная спецификация Java, описывающая стандарты работы с сеттерами.
- Reddit Discussion on Returning 'this' in setters — обсуждение плюсов и минусов использования Fluent Setters в Java.
- Fluent Setters for Better Code Readability – DZone — глубокое понимание преимуществ Fluent Setters для повышения читабельности кода.