Является ли неправильной практикой, чтобы мой метод getter менял сохраненную ценность?

Является ли неправильной практикой изменять мой метод getter, как версия 2 в моем классе.

Версия 1:

 public String getMyValue(){
     return this.myValue
 }

Версия 2:

 public String getMyValue(){

    if(this.myValue == null || this.myValue.isEmpty()){
       this.myValue = "N/A";
    }

    return this.myValue;
 }

Ответ 1

Я думаю, что это на самом деле довольно плохая практика, если ваши методы getter изменяют внутреннее состояние объекта.

Чтобы добиться этого, я бы предложил просто вернуть "N/A".

  • В общем случае это внутреннее поле может использоваться в других местах (внутри), для которых вам не нужно использовать метод getter. Итак, в конце концов, вызов foo.getMyValue() может действительно изменить поведение foo.

В качестве альтернативы, перевод с null на "N/A" может быть выполнен в сеттер, то есть внутреннее значение может быть установлено на "N/A", если передано null.


Общее замечание:
Я бы добавил только такие состояния, как "N/A", если они ожидаются некоторым API или другим экземпляром, полагающимся на ваш код. Если это не так, вы должны полагаться на стандартные типы нулей, доступные вам на вашем языке программирования.

Ответ 2

По моему мнению, если вы не делаете lazy-loading (которого вы не в этом случае), геттеры не должны изменять значение. Поэтому я бы:

Поместите изменение в установщик

public void setMyValue(String value) {
    if(value == null || value.isEmpty()){
        this.myValue = "N/A";
    } else {
        this.myValue = value;
    }
}

Или заставить getter вернуть значение по умолчанию, если значение не установлено должным образом:

public String getMyValue() {
    if(this.myvalue == null || this.myvalue.isEmpty()){
        return "N/A";
    }    
    return this.myValue;
}

В случае ленивой загрузки, где я бы сказал, что изменение ваших членов в getter в порядке, вы бы сделали что-то вроде:

public String getMyValue() {
    if (this.myvalue == null) {
        this.myvalue = loadMyValue();
    }    
    return this.myValue;
}

Ответ 3

Нет. Здесь вы делаете две вещи. Получение и настройка.

Ответ 4

Да. Это плохая практика.

Зачем?

Когда значение установлено (в методе конструктора или метода установки), оно должно проверяться, а не когда вызывается метод получения. Создание private метода validate* для этого также является хорошей идеей.

private boolean validateThisValue(String a) {
     return this.myValue != null && !this.myValue.isEmpty();
}

public void setThisValue(String a) {
    if (validateThisValue(a)) {
        this.myValue = a;
    } 
    else {
        // do something else
        // in this example will be
        this.myValue = "N/A";
    }
}

И в методе получения никогда не меняйте состояние объекта. Я работал над некоторыми проектами, и получатель часто должен быть const: "этот метод не может изменить внутреннее состояние".

По крайней мере, если вы не хотите усложнять ситуацию, в методе получения вы должны вернуть "N/A" а не изменять внутреннее состояние и установить myValue в "N/A".

Ответ 5

Я обычно определяю конкретный getter.

Никогда не меняйте оригинальный getter:

 public String getMyValue(){
     return this.myValue
 }

И создайте определенный getter:

public String getMyValueFormatted(){

    if(this.myvalue == null || this.myvalue.isEmpty()){
       return "N/A";
    }else{
       return this.myValue;
    }
 }

Ответ 6

Я думаю, что лучше инициализировать this.myValue = "N/A". И последующие вызовы setMyValue должны изменить this.myValue в соответствии с вашими бизнес-условиями.
getMyValue не должен каким-либо образом изменять this.myValue. Если ваши потребности возвращают определенное значение, вы должны вернуть это значение (например, "N/A" ), а не изменять this.myValue. Getters не должны изменять значение члена.

Ответ 7

Я бы лучше изменил метод setter, поэтому, если значение null или пустое, этому атрибуту присваивается N/A. Таким образом, если вы используете атрибут в других методах внутри класса (v.g. toString()), у вас будет указанное значение.

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

Кроме этого, это нормально.

Ответ 8

Я чувствую, что это плохая практика, пока и пока вы не объясните причину, почему это так необходимо, чтобы вы изменяли объект внутри метода getter, а не выполняли его внутри метода setter.
Считаете ли вы, что это невозможно сделать по какой-то причине? Не могли бы вы уточнить?

Ответ 9

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

Но если вы используете фреймворки типа Spring, вы обязаны использовать эти стандартные имена, и вы никогда не должны вводить свои собственные коды внутри них.

Ответ 10

Установщик может изменять как часть проверки, но получатель должен вернуть значение и позволить проверке выполнить вызывающий. Если вы сделаете, то как следует документировать.

Ответ 11

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

Если вы определяете свой контракт, чтобы метод get() не позволял изменять объект, то вы нарушаете свой собственный контракт. Подумайте о реализации метода типа

public isValid() {
    return (this.myvalue == null || this.myvalue.isEmpty());
}

Преимущество такого подхода заключается в том, что вам не нужно проверять, чтобы возврат вашего get() был "N/A" или что-то еще. Это также можно вызвать перед вызовом set() для проверки того, что вы не вставляете незаконные значения в свой объект.

Если вы хотите установить значение по умолчанию, вы должны сделать это во время инициализации.

Ответ 12

абсолютно да, это плохая оценка.

Представьте, что вы общаетесь по сети с третьей стороной (удаленный, COM,...), это увеличит время прохода туда, а затем ударит производительность приложения.

Ответ 13

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

Ответ 14

Для этой цели вы можете использовать некоторый держатель ценности. Подобно необязательному классу в библиотеке guava.