Методы получения и установки объектов сущностей для свойств данных

StackOverflow https://stackoverflow.com/questions/406288

Вопрос

Недавно я начал работать с Java и познакомился с диким и сумасшедшим миром геттеров и сеттеров для всего.Поначалу я ненавидел это, но быстро привык.Слишком привык.

В последнее время я провожу много времени, думая о дизайне классов.Одна из вещей, которую я пытаюсь сделать, — это избежать ловушки выполнения геттеров и сеттеров для всего.Однако большая часть работы, которую я делаю, связана с сущностями, которые в основном являются контейнерами данных, и я не уверен, что геттеры и сеттеры действительно не подходят в этих случаях.

Вот простой пример использования общедоступных свойств.

class Space {
    public String name;
    public String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
}

Вот простой пример использования частных свойств и использования геттеров и сеттеров.

class Space {
    private String name;
    private String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
    public String getName() {
        return this.name;
    }
    public void setName(final String name) {
        this.name = name;
    }
    public String getDescription() {
        return this.description;
    }
    public void setDescription(final String description) {
        this.description = description;
    }
}

В этих примерах оба name и description поля должны иметь возможность изменяться.

Мне кажется, что пример получения/установки более понятен и скрывает детали реализации того, что name и description являются.Это также позволит провести проверку на съемочной площадке позже, если это необходимо.

Я читал несколько дискуссий о том, что геттеры и сеттеры являются злом и/или антишаблоном, но мне кажется, что они могут неприменимы к данной ситуации.

Возможно, есть какие-то варианты, которые я еще не рассматривал.Я открыт для предложений!

Это было полезно?

Решение

Проще говоря:

  • Вам нужны геттеры для всех полей, которые необходимо прочитать извне.
  • Вам нужны сеттеры для всех полей, которые должны быть написаны извне.

Это может быть 100%, но в большинстве случаев меньше.

Другие советы

Первая версия (публичные свойства) — не лучшая идея.Второе лучше.Как сказал бы Джош Блох: «за неизменность»:

public class Space {
    private final String name;
    private final String description;

    public Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }
}

Что, как говорится, геттеры и сеттеры, как правило, злоупотребляют.

Вы слышали часто упрощенную фразу «get/setters — это зло».Никто (надеюсь) Действительно означает, что с объектами данных что-то не так.Я думаю, что настоящая идея такова:

«Геттеры/сеттеры — это зло, за исключением простых объектов хранения данных», что само по себе является просто евангелизмом «говори, не спрашивай».

В идеале, если в классе есть геттеры и сеттеры, это все так и должно быть.

В любом случае это аргумент.Я не уверен, что согласен с этим.

Хотя шаблон доступа помогает скрыть детали реализации класса (например,используя хэш-таблицу для хранения атрибутов для экономии памяти на редко используемых классах), ее реализация может быть очень многословной (ваш пример содержит еще 12 строк с аксессорами).Вот почему в C# имеется специальный синтаксис свойств, который позволяет кратко указывать методы доступа по умолчанию:

class Space {
    public String Name { get; set; }
    public String Description { get; set; }
    Space(final String name, final String description) {
        this.Name = name;
        this.Description = description;
    }
}

Альтернативные формы могут добавлять спецификаторы доступа и/или код:

private String _name;
public String Name {
    get { if (_name == null) FetchName(); return _name; }
    private set { _name = value; }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top