Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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.

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.

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.

In C++ I just use overloading

int parameter() const { return m_param }
void parameter(int param) { m_param = param; }

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.

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.

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.

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!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top