Объекты получения и установки объектов сущности для свойств данных - PullRequest
2 голосов
/ 02 января 2009

Я недавно начал работать на 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. Это также позволило бы проверить правильность установки позже, если это необходимо.

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

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

Ответы [ 4 ]

6 голосов
/ 02 января 2009

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

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;
    }
}

Как говорится, геттеры и сеттеры, как правило, чрезмерно используются .

4 голосов
/ 02 января 2009

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

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

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

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

3 голосов
/ 02 января 2009

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

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

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

0 голосов
/ 02 января 2009

Хотя шаблон средства доступа помогает скрыть подробности реализации класса (например, используя хеш-таблицу для хранения атрибутов для экономии памяти в редко используемых классах), его реализация может быть очень многословной (в вашем примере имеется еще 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; }
}
...