Is it bad practice to have my getter method change the stored value?

ClassLazy LoadingLazy EvaluationGetter Setter

Class Problem Overview


Is it bad practice to change my getter method like version 2 in my class.

Version 1:

 public String getMyValue(){
     return this.myValue
 }

Version 2:

 public String getMyValue(){

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

    return this.myValue;
 }

Class Solutions


Solution 1 - Class

I think it is actually quite a bad practice if your getter methods change the internal state of the object.

To achieve the same I would suggest just returning the "N/A".

  • Generally speaking this internal field might be used in other places (internally) for which you don't need to use the getter method. So in the end, the call to foo.getMyValue() could actually change the behaviour of foo.

Alternatively, the translation from null to "N/A" could be done in the setter, i.e. the internal value could be set to "N/A" if null is passed.


A general remark:
I would only add states such as "N/A" if they are expected by some API or other instance relying on your code. If that is not the case you should rely on the standard null types that are available to you in your programming language.

Solution 2 - Class

In my opinion, unless you are doing lazy-loading (which you are not in that case), getters should not change the value. So I would either:

Put the change in the setter

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

Or make the getter return a default value if value not set properly:

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

In the case of lazy-loading, where I would say that changing your members in a getter is fine, you would do something like:

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

Solution 3 - Class

No. You're doing two things here. Getting and setting.

Solution 4 - Class

Yes. It's a bad practice.

Why?

When the value is set (in a constructor or setter method), it should be validated, not when a getter method is called. Creating a private validate* method for this is also a good idea.

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

And, in the getter method, never ever change the state of the object. I have worked on some projects, and the getter often must be made const: "this method cannot change internal state".

At least, if you do not want to complicate things, in the getter method, you should return "N/A" rather than change internal state and set myValue to "N/A".

Solution 5 - Class

I usually define a specific getter.

Never alter original getter:

 public String getMyValue(){
     return this.myValue
 }

And create a specific getter:

public String getMyValueFormatted(){

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

Solution 6 - Class

I think it's better to initialize this.myValue = "N/A". And subsequent calls to setMyValue should modify the this.myValue according to your business conditions.
The getMyValue shouldn't modify in any way this.myValue. If your needs are to return a certain value, you should return that value (like "N/A") and not alter this.myValue . Getters must not modify member's value.

Solution 7 - Class

I would change better the setter method so, if the value is null or empty, the N/A is assigned to the attribute. So, if you use the attribute in other methods inside the class (v.g. toString()) you will have the intended value there.

Alternatively, change the setter method to launch an exception when the value being set is not right, so the programmer is forced to improve its handling prior to setting the value.

Other than that, it is ok.

Solution 8 - Class

I do feel this is a bad practice unless and until you explain the reason why it is so necessary for you modify the object inside the getter method instead of doing it inside the setter method.
Do you feel this cannot be done for some reason? Could you please elaborate?

Solution 9 - Class

Do what ever you like. After all getters and setters are just another public methods. You could use any other names.

But if you use frameworks like Spring, you are bound to use those standard names and you should never put your custom codes inside them.

Solution 10 - Class

absolutely yes, it's a bad pratice.

Imagine you communicate accross network with a third party (remoting, COM, ...), this will increase the round-trip and then hit application performance.

Solution 11 - Class

A setter could modify as part of validation, but a getter should return the value and let the validation be done by the caller. If you do validate, then how should be documented.

Solution 12 - Class

This actually highly depends on the contract you want to enforce with your get()-method. According to design-by-contract conventions the caller has to make sure that the preconditions are met (which means doing a validation in a setter method often is actually bad design) and the callee (I do not know if that's the correct english term for that, i.e., the called one) makes sure that the post conditions are met.

If you define your contract so that the get()-method is not allowed to change the object then you are breaking your own contract. Think about implementing a method like

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

Advantage of this approach is that you do not have to check wether the return of your get() is "N/A" or something else. This also can be called before calling set() to validate that you do not insert illegal values into your object.

If you want to set a default value you should do that during initialization.

Solution 13 - Class

State changes in getters should be a hanging offence. It means that client code must be careful about the order in which it accesses getters and setters and to do this it must have knowledge of the implementation. You should be able to call the getters in any order and still get the same results. A related problem occurs when the setter modifies the incoming value depending on the current state of the object.

Solution 14 - Class

You can use some value holder for this purpose. Like Optional class in guava library.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsomeoneView Question on Stackoverflow
Solution 1 - ClassfgysinView Answer on Stackoverflow
Solution 2 - ClassVincent Mimoun-PratView Answer on Stackoverflow
Solution 3 - ClassMark WView Answer on Stackoverflow
Solution 4 - ClasshqtView Answer on Stackoverflow
Solution 5 - ClassRodrigoView Answer on Stackoverflow
Solution 6 - ClassGeorge DView Answer on Stackoverflow
Solution 7 - ClassSJuan76View Answer on Stackoverflow
Solution 8 - ClassrameshView Answer on Stackoverflow
Solution 9 - ClassMawiaView Answer on Stackoverflow
Solution 10 - ClassxPridexView Answer on Stackoverflow
Solution 11 - ClassBizmarckView Answer on Stackoverflow
Solution 12 - ClassLucas HoepnerView Answer on Stackoverflow
Solution 13 - ClassKevin WhitefootView Answer on Stackoverflow
Solution 14 - ClassAleksander GralakView Answer on Stackoverflow