2009-01-02 2 views
2

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

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

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

ответ

3

Выражаясь просто:

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

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

+0

Я допускаю это, возможно, были ответ, который я искал. –

+0

«со стороны» означает что? Если поля являются общедоступными, они доступны. Это больше похоже на C "struct". Если объект должен быть изменен и проблем с потоками нет, нет проблем. –

6

Первая версия (публичные объекты) - это не очень хорошая идея. Второй - лучше. Как Джош Блох бы сказал, "favor immutability":

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

, как говорится, getters and setters tend to be overused.

4

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

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

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

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

0

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