Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Something I really have not thought about before (AS3 syntax):

private var m_obj:Object;
protected function get obj():Object
{
    return m_obj;
}

private var m_str:String;
protected function get str():String
{
    return m_str;
}

At least subclasses won't be able to set m_obj or m_str (though they could still modify m_obj).

My question: Is this just blatant overkill?


This Programmer's question: When or why should one use getters/setters for class properties instead of simply making them public properties? has been suggested as a duplicate.

That question is different because it only addresses public vs. private properties and whether a property should be wrapped with getters & setters. For my question, I'm focusing on protected variables and how inheriting classes would interact with those variables.

So the alternative implementation would be:

protected var m_obj:Object; //more accessible than a private variable with a protected getter
protected var m_str:String; //more accessible than a private variable with a protected getter

My question is similar because I am talking about using trivial protected getters to block subclasses from writing to the variables, but to allow them all other access.
In languages like AS3, this will even allow them to make any changes to mutable object variables, as long as the references themselves are not modified.

share|improve this question
2  
ask yourself; is it dangerous that subclasses can set it to something arbitrary if the answer is yes then it isn't overkill –  ratchet freak Oct 24 '13 at 13:15
1  
I edited the question to make it more clear what I'm talking about not doing instead. –  Panzercrisis Oct 24 '13 at 14:01

4 Answers 4

up vote 4 down vote accepted

Is this just blatant overkill?

Often times it is, sometimes it's not.

Keeping m_obj in some known good state helps protect the Liskov Substitution Principle, keeping your code more resilient and higher quality. Sometimes you can trust inheritors to respect that behavior, sometimes you can't (either due to usage pattern or the subtlety of the contract it implements). Though this code/question also stumbles towards some of the reasons for "Why is Clean Code suggesting avoiding protected variables?"

share|improve this answer
    
Is it sometimes worth it when the subclasses could still do just about anything they want to m_obj except set it to null or another instance? –  Panzercrisis Oct 24 '13 at 14:45
    
@Panzercrisis - it depends on the language. In non-memory managed languages, setting it to null/something else is a big deal. –  Telastyn Oct 24 '13 at 15:22

Trivial protected getters have at least two practical advantages over an exposed variable:

  • For debugging, they are a perfect place to put a conditional breakpoint which triggers when “that funny value gets into your program”. It is much harder to get the same control if you access the value directly.

  • For mocking an object, if you are using this method to test descendants.

The cost of using getters is virtually zero, so there is no real reason not to use them. Is there?

share|improve this answer
    
Thank you. The question has been edited for clarity though. –  Panzercrisis Oct 24 '13 at 14:05
    
My answer does not refer to the public or protected attribute of the getter! :-) –  Michael Grünewald Oct 24 '13 at 14:07
    
Oh, sorry about that. –  Panzercrisis Oct 24 '13 at 14:08
1  
The cost is in the code bloat. The cost is not large, but it's greater than zero. Sure, the getters are trivial, but they have to be passed over every time someone works on the class. And they can be wrong: get x() ... { return _y; } No one would ever type that, but it might happen due to an incorrect cut-and-paste. –  kevin cline Oct 24 '13 at 19:17
1  
It's a tradeoff between different costs, though. And in my experience the cost of tracking down bugs where subclasses compromise their parent class in subtle ways is huge compared to the cost of maintaining getters and setters. –  Julia Hayward Nov 6 '13 at 9:53

No matter if you use getters or field access, any experienced reviewer will find out the issue in your design and complain that your objects expose data instead of behavior.

Note that appealing to "protected" won't help, because the purpose of inheritance is to allow subclasses adjust / tune behavior of the parent (LSP), not to justify indiscriminate messing with parent data. As Bertrand Meyer puts it,

Neither the Open-Closed principle nor redefinition in inheritance is a way to address design flaws... (The only potential exception for this rule is the case of flawed software which you are not at liberty to modify.)

"Getters are evil" reasoning applies irrespectively on whether you spell get explicitly or mask it behind the field access.

see this article or this article by Alan Holub...

You shouldn't use accessor methods (getters and setters) unless absolutely necessary because these methods expose information about how a class is implemented and as a consequence make your code harder to maintain. Sometimes get/set methods are unavoidable, but an experienced OO designer could probably eliminate 99 percent of the accessors currently in your code without much difficulty.

Getter/setter methods often make their way in code because the coder was thinking procedurally. The best way to break out of that procedural mindset is to think in terms of a conversation between objects that have well-defined responsibilities...

If you are seriously concerned about the issue, first thing to consider is redesign of the code to get rid of both getters and non-private field access, instead of playing fruitless mind games picking which way is least inappropriate.

Worth stressing once again, hiding troublesome design behind "protected" smokescreen won't make the problem go away - inheritance does not justify tricks like that. Paraphrasing your question, strive to design things in a way that avoids having inheriting classes interact with those variables at all - neither via getters nor via field access. Tell, don't ask:

Procedural code gets information then makes decisions. Object-oriented code tells objects to do things.

Spending time and effort on deciding which way to prefer to get information, against classical principle recommending to avoid this altogether, now that sounds like a blatant overkill to me.

share|improve this answer

In the case of an immutable class implementation, making your internal variables protected would break the contract you have set, in which case the protected getters would not be overkill andnecessary (though you would have to return copies of your variable, not a pointer to it).

In mutable classes, I still prefer getters/setters to granting direct access to my internal variables. This makes sure that you can change how you handle your internal variables as you wish, without fear of breaking any client code. For instance, imagine you have a Java class as follows:

public abstract class SomeClass {
    protected int[] someVariable;

    // Rest of implementation
}

Client class extending SomeClass would then directly access someVariable, manipulating it how they see fit. Now, this can create all sorts of problems if these classes do not leave someVariable in an acceptable state. Moreover, if you decide in a subsequent release to change the definition of SomeClass to use a List<Integers> instead of an array, you will then break compatibility with the existing code base, which expect SomeClass to have an internal array of ints, not a list of ints.

Using protected getters in this case would allow you to make this change without breaking any pre-established contract.

public abstract class SomeClass {
    List<Integer> someVariable;

    protected int[] getSomeVariable () {
        // Return int[] version of someVariable
    }

    // Rest of implementation
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.