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.

I notice that web related code uses setter methods to set class fields instead of setting them directly since they are in scope. I find this to be a bit odd. Using setters is certainly safer, but if unit tests are implemented then bugs will be found. And it's not worth the extra stack call, imo.

Does any production code do this or is this just what you see in sample code online?

Edit: I have to make clear that I'm only talking about the case whereby the setter consists solely of a single assignment expression and nothing more.

share|improve this question
    
I know I was taught in school to ALWAYS use the getter and setter functions, even within the class. Of course, that was 10 years ago and web apps weren't so much a thing back then. –  Amy Anuszewski Aug 26 '11 at 2:59
1  
Using what language? In C# I very much prefer writing public int Age { get; private set; } to any other way to use getters and setters in an OOP language. –  Job Aug 26 '11 at 3:07
7  
"not worth the extra stack call" - be careful of early optimization! –  user1249 Aug 26 '11 at 7:54
2  
Are you sure this only a performance question or isn't it also an encapsulation/abstraction one ? –  David Aug 26 '11 at 9:23
1  
You're forgetting that the set() function may actually DO something, if you start poking at variables directly they may bite back. You're also forgetting that nothing is an optimization problem until it's measured and found to be a problem. –  Patrick Hughes Aug 27 '11 at 18:36
show 3 more comments

6 Answers

up vote 4 down vote accepted

You should follow the open/closed principle. Not using the setter means your class is not open to extension, because subclasses overriding the setter to maintain internal consistency by adding some according logic within the call will not have that logic executed and thus wind up with an inconsistent state.

As opposed to that, the argument with the extra call is virtually void.
Either the setter is overriden in a subclass, which means not using it is strictly not an option. Or the setter is not overriden, in which case any decent (JIT) optimizer will be able to inline it and thus achieve the same performance.

share|improve this answer
    
All good answers. The clincher is the inlining by an optimizing compiler and then this open/closed prinicple which I forgot. Thanks everyone. –  Tom Jones Aug 27 '11 at 0:55
add comment

Never, ever, depend on unit tests when you can not depend on them. Safety 101: Guarantee it at compile-time instead of hoping, testing, or checking for it at run-time. If you have a setter for a variable, it's for a good reason, and you should not circumvent it without an even better reason.

share|improve this answer
3  
Sounds like you are reciting a rule or guideline. Do you have a reference of some sort? An author, textbook, etc.. –  Tom Jones Aug 26 '11 at 3:03
8  
@Tom Jones: It's common sense to guarantee safety at compile-time if you have the option. –  DeadMG Aug 26 '11 at 3:12
2  
@Tom Jones: He gave it to you: "Safety 101" ;) ... I don't think there's a particular source for this. It's really just common sense. I've seen many people say this or a corollary of it in one way or another. –  back2dos Aug 26 '11 at 9:55
1  
Common sense my ass. At the very least give the reasoning like these other folks did. Why do people think that people will just believe whatever they say, esp on a site like this that insists on references. –  Tom Jones Aug 27 '11 at 0:54
3  
@Tom The reasoning is trivial: the earlier a failure can be detected, the better, since no individual component is error-free. If you don’t have to rely on a unit test, don’t rely on it, since any test can be flawed. Static checking in compilers is much more heavily tested, and fails much more rarely, than your custom unit tests. Thus failing early has exactly one (primary) effect: it reduces the chance of failure (which is always nonzero). –  Konrad Rudolph Aug 27 '11 at 11:39
show 2 more comments

To the performance aspect, a modern Just In Time compiler will In-Line the setter call if it is truly just a trivial set. There's no allocation of a new method stack or any of that cost to consider. Avoiding using getters/setters isn't really a performance concern even as a micro-optimization. (yes there is a cost to perform the inline, but the question refers to webapps, where ostensibly that happens once and the server remains up indefinitely.)

So some things in favor of using the setters

1) The setter may not be just a simple set for all time. I guess this is some personal opinion, but hoping automated tests will catch any and all bugs possibly introduced by skipping a setter that later gains side effects seems naive.

2) Set methods may be instrumented at run time by other frameworks. Persistence systems and aspect oriented programming frameworks can both add additional functionality to set methods that isn't seen in the source of the class. And again, just because one isn't in use now, doesn't mean it never will be.

3) A field that is accessed via a set method is clearly externally visible and changable state, as opposed to a truly private field with no accessors that is clearly internal state. It can improve understanding if the fields that represent only internally managed state "stand out" in code for lacking set calls.

4) Fewer worries about bugs where people leave off the 'this.' and set a method scope variable instead of the instance scope variable that they hid sloppily. (It's amazing how many people have conditioned themselves to completely ignore compiler warnings, even in IDEs that highlight them.)

In favor of not using the setter

1) All I can come up with is some people may find it easier to read.

share|improve this answer
1  
+1 for #1. Code evolves. It's just an assignment today, but tomorrow? Or two years from now? Perhaps it won't be. –  Dave Sherohman Aug 26 '11 at 9:13
add comment

A lot of it goes back to Bertrand Meyer's book and his Uniform Access Principle, or else with the Bean standard.

If we aren't filtering or massaging the data in our getter/setters I don't see a lot of point in writing getter/setter methods. If you have 'int getX()' and you change the implementation to double, you still will lean on the compiler to find the places to change. Likewise if you want to add an edit to an old public member.

Most people follow the rule slavishly. Why don't you try breaking it sometimes and seeing what it teaches you? Think about what situations would warrant additional wrapping, and when it is wasted effort. Keep notes.

share|improve this answer
    
Yes, I didn't start seeing this until Java Beans came out. Also, most auto-generated code tends to use setters in this way. Personally, I've always used a setter if the method did more than a simple assignment otherwise it seems silly. Each case is different. I just wanted to make sure I didn't miss some new way of doing things. –  Tom Jones Aug 26 '11 at 3:34
add comment

In object oriented code, where the setters/getters of child classes can be different, you should always use them.

share|improve this answer
add comment

what constitutes a valid value and the accessor's implementation changes more often than you should care to manage manually.

it's highly tedious and error prone to verify all direct accesses follow the requirements set by the setter when implementations change. at that point, you realize you are validating and copying code all over that place (well, there are a lot of programmers that just trust they will not introduce a bug), which only makes the problem worse by giving you more implementations to validate manually and more chances for error. as the program evolves, it's easier and simpler to always use the setter and just move on with life.

in some cases, you will need direct access. this varies by language, but is common during initialization and destruction.

regarding performance: if the cost of function calls is a valid performance problem, you may be using the wrong tools, language, or approach. i do a lot of work in c++ -- the cost is trivial to nothing in optimized builds if well written. other languages are not as good in that regard.

share|improve this answer
add comment

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.