Когда используют сеттеры (setter-методы)?

Ответ

Сеттеры — это публичные методы для изменения приватных полей объекта. Их основное назначение — обеспечить инкапсуляцию, то есть скрыть внутреннее представление данных и контролировать способ их модификации.

Использую сеттеры, когда нужно:

  1. Добавить валидацию. Прежде чем присвоить значение, можно проверить его корректность.
  2. Выполнить побочные действия. Например, логировать изменение, уведомлять наблюдателей или пересчитывать зависимые поля.
  3. Сохранить инварианты объекта. Гарантировать, что внутреннее состояние всегда остается согласованным.

Пример на Java:

public class BankAccount {
    private String owner;
    private double balance;

    // Сеттер с валидацией
    public void setOwner(String owner) {
        if (owner == null || owner.trim().isEmpty()) {
            throw new IllegalArgumentException("Owner name cannot be empty");
        }
        this.owner = owner.trim();
    }

    // Сеттер с бизнес-логикой и поддержанием инварианта (баланс не отрицательный)
    public void deposit(double amount) { // Это тоже вид "сеттера" для баланса
        if (amount <= 0) {
            throw new IllegalArgumentException("Deposit amount must be positive");
        }
        this.balance += amount;
        this.lastTransaction = LocalDateTime.now(); // Побочное действие
    }

    // Геттер
    public double getBalance() {
        return balance;
    }
}

Когда сеттеры не нужны: Для простых DTO (Data Transfer Objects) или Value Objects, которые являются всего лишь контейнерами для данных без поведения. В таких случаях можно использовать публичные поля final или record в Java.

Ответ 18+ 🔞

Ну и история с этими сеттерами, блядь. Смотри, в рот меня чих-пых, это ж просто публичные методы, которыми ты меняешь приватные поля. А главная их фишка — инкапсуляция, ёпта. То есть ты прячешь всю свою внутреннюю кухню, а наружу выставляешь только дверцу, да ещё и с замком.

Вот когда эти сеттеры реально нужны, как воздух:

  1. Валидация на входе, ёбана. Нельзя же просто так, с бухты-барахты, любую хуйню в объект пихать. Представь, что кто-то пытается твоему банковскому счёту владельца с пустым именем присвоить. Да похуй? Нет, не похуй! Вот сеттер и впендюрит исключение, типа "Иди нахуй со своим null'ом".
  2. Побочные действия. Изменил поле — и тут же, блядь, логирование сработало, или уведомление куда-то ушло, или ещё какая хитрая жопа подтянулась. Без сеттера пришлось бы это вручную везде копипастить, а это пиздопроебибна.
  3. Чтобы инварианты не посрались. Это чтобы внутреннее состояние объекта не превратилось в манду с ушами. Например, баланс не должен уходить в минус. Правильный сеттер (или метод типа deposit) тебе этого не позволит, а тупо присвоить balance = -1000; — запросто.

Вот тебе живой пример, смотри:

public class BankAccount {
    private String owner;
    private double balance;

    // Сеттер с валидацией. Попробуй пустое имя передать — получишь по ебалу.
    public void setOwner(String owner) {
        if (owner == null || owner.trim().isEmpty()) {
            throw new IllegalArgumentException("Owner name cannot be empty");
        }
        this.owner = owner.trim();
    }

    // А это типа умный сеттер для баланса. Не просто присвоить, а с логикой.
    public void deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Deposit amount must be positive");
        }
        this.balance += amount;
        this.lastTransaction = LocalDateTime.now(); // Глянь, побочка! Записали время.
    }

    // А это геттер, он просто отдаёт, не трогай его.
    public double getBalance() {
        return balance;
    }
}

А когда их нихуя не нужно? Да когда у тебя простой контейнер для данных, этакая тележка. DTO там или Value Object. Там никакой логики, просто поля туда-сюда таскать. В таких случаях можно и публичными полями обойтись, или в Java record использовать — и волосы дыбом не встанут. Зачем там сеттер, если он будет просто this.field = field;? Хуй с горы, одно разочарование.