views:

417

answers:

11

Does this rankle anyone else out there? I would much rather see:

 block.key(newKey);  // set the key for this block

and

 testKey = block.key();  // look up the key for this block

than

 block.setKey(newKey); // set the key for this block
 testKey = block.getKey(); // look up the key for this block

First, the "set" and "get" are redundant (and hence add noise reducing the readability). The action (set/get) is defined by the syntax of each statement. I understand the overloading. In fact, using the same exact identifier reinforces that these are the same property of the object. When I read "getKey()" and "setKey()" I may not be so sure.

Second, if "get" and "set" are to be strictly interpreted as setter and getter, then if other semantic associated with setting/getting a value, side effects for example, will be surprising.

I suppose this bias comes from my Smalltalk background, but in a world where polymorphism works just fine, wouldn't we be better off without the "get" and "set" sprinkled everywhere? Just think of how much more code we could type if we didn't have to type those three letters over and over again?! (tongue somewhat in cheek)

Anyone out there feel the same way?

+3  A: 

For me, get and set prefixes make my brain do less work when reading code. When used consistently, get/set methods make it easier to grep a header, possibly making the class easier to learn & use. I spend a disproportionately large amount of time reading code vs. writing code, so the extra characters for get and set are fine by me.

Pete
As you reflect on how get/set helps you read code, when you encounter block.setKey(newKey); do you create a mental model of a simple private variable with an accessor, whereas if you read block.key(newKey);are you more likely to build a more complicated or nuanced mental model?Does the set/get convention violate information hiding principles?
Mark Laff
@Mark, I don't think of it as storing a private variable, nor do I think that it violates information hiding. setKey/getKey could store an integer in memory, a row in a database, text to a file, etc. but it doesn't really matter. set/get methods either store or retrieve something from somewhere.
Pete
+5  A: 

The designers of C# apparently agree, and the 'C#' tag outnumbers the next most popular language by 2:1 on StackOverflow. So I suspect you're preaching to the choir.

Richard Berg
+1 for mathematical proof of correctness.
Stefan Kendall
+3  A: 

Several languages have different ways of handling getters and setters. In Java you have getName and setName, in Qt you have name and setName. I prefer the Java way for these reasons:

  1. What if you have a function that is called drive? Does it cause your class to drive, or does it set/get a drive?
  2. With suggestions turned on, you can type get, and then get all the getters. This is very useful if you don't remember the name of a getter you need.
  3. Building on reason one, it separates the functions into different groups. You have the functions that do something, they don't start with get or set (though maybe they should start with do?). Then you have the functions that get a property, and they all start with get. Then you have the functions that set a property, and they all start with set.
Marius
Your points #2 and #3 come dangerously close to endorsing the Hungarian notation wholesale - beware! ;)
Pavel Minaev
The words Drive and Driver aren't related in your usage. A better example would be whether Drive means to set a property or cause an action.
Chris Lively
Thank you Chris, just wrote a bit too fast :)Pavel, I hate Hungarian notation, but I love getName and setName. The difference is that one describes what each method does, while the other describes what they are, which is already known. Also, Hungarian notation affects what happens inside my class, where I can make things as messy as I like, as long as it looks clean from the outside.
Marius
+1  A: 

Yes the get/set in java is essentially a workaround a problem in the language.

Comparing it to c# properites

http://www.csharp-station.com/Tutorials/Lesson10.aspx

Or python http://blog.fedecarg.com/2008/08/17/no-need-for-setget-methods-in-python/

I think this is one of biggest failings of java.

Brendan Heywood
The URL of the Python link is funny, since the blog post actually suggests implementing get/set methods in Python, but mask them to the member name via `property`.
Pete
A: 

C# getters and setters are "first class" entities and don't resemble function calls syntactically (though any arbitrary code can run in the context of an accessor).

I only use get/set in languages that force me to, like Objective-C.

ראובן
+2  A: 

Prefixing accessors with "get" and mutators with "set" is a practice that varies from language to language, and seems to be mostly prevalent in Java. For example:

  • In Python, you have the concept of properties, and so an accessor might look like obj.foo and a mutator might look like obj.foo = bar (even though methods are called behind the scenes). Similar concepts exist in languages such as Ruby. So in a lot of languages, calls to accessors and mutators look like direct "calls" to instance variables, and you never see anything like "setFoo" or "getFoo".
  • Languages such as Objective-C discourage the practice of prefixing accessors with "get", so in Objective-C you'd see calls like [obj foo] and [obj setFoo:bar].

I never liked the practice of prefixing accessors in Java with "get", either, but I do see the merit in prefixing mutators with "set". That said, since the prevailing practice is to prefix with "get"/"set" in Java, I continue the trend in my own code.

mipadi
@mipadi I agree that the prevailing practice is an important factor...probably trumps any stylistic optimization in this area. As the saying goes, "that ship has sailed", and the discussion here underlines the valid perspectives on both sides of the issue.
Mark Laff
+2  A: 

In C++ I just use overloading

int parameter() const { return m_param }
void parameter(int param) { m_param = param; }
Martin Beckett
You probably want to make that "int parameter()const{ return m_param; }".
Michael Aaron Safyan
Thanksm do you bother doing parameter(const int param) for simple types?
Martin Beckett
Personally, I'm slightly less likely to mark an int parameter as const, than I am to mark an int declared in the function as const. For example when I write functions that take iterator pairs for ranges, I do sometimes do my_algorithm(ForwardIterator current, const ForwardIterator last) instead of first/last. So I can increment current and not last. But that's confusing in a declaration, especially if documentation is going to be generated from it, because I've named them from the POV of the implementation instead of from the POV of the caller. So it's only for internal stuff and definitions.
Steve Jessop
... it's also of minor benefit, since algorithms which want to decrement the end iterator are rare enough that modifying "last" always looks suspicious anyway, without marking it const. Likewise with most function parameters, modifying them in the function body is usually obviously OK (like when you clamp to range), so const-ing the ones you don't plan to modify is nice but not necessary IMO.
Steve Jessop
+2  A: 

In general property names should be nouns whereas method names should be verbs, so the property in the above example would be called 'driver' and the method would be 'drive'. There will of course be cases where there is overlap but in general this works and makes the code more readable.

Gary
A: 

You can easily search your codebase for references to getDrive() or setDrive(). If your method is just named 'drive', you will get many more false positives when searching.

too much php
+3  A: 

The Java language currently doesn't have properties, so the getter / setter syntax has become the de-facto standard. If your writing Java code, you'll be well served to use the Java convention. This isn't just so other programmers can read your code, but more importantly hundreds of other Java frameworks are built to handle objects supporting Java Bean style getters / setters.

For example, in the Velocity templating engine, you could write something like:

The answer is $block.key

The above will attempt to invoke:

block.getkey();
block.getKey();

If you've defined block.getKey(), then all will work fine. Generally it's best to follow the conventions of the language.

brianegge
A: 

Hear, hear.

I really like special notation for getters and setters. CLU did this best:

  • Using p.x in an expression was equivalent to the call get_x(p).

  • Using p.x := e (assignment) was equivalent to the call set_x(p, e).

If the interface for object p didn't export get_x or set_x, you were prevented from doing the corresponding operation. Simple.

Let's hear it for syntactic sugar!

Norman Ramsey
I don't like that, it makes it look like you're not calling a method, which could have other things going on in it.
Mk12