views:

464

answers:

12

Apart from unambiguous clarity, why should we stick to:
car.getSpeed() and car.setSpeed(55)
when this could be used as well : car.speed() and car.speed(55)

I know that get() and set() are useful to keep any changes to the data member manageable by keeping everything in one place.

Also, obviously, I understand that car.speed() and car.speed(55) are the same function, which makes this wrong, but then in PHP and also in Zend Framework, the same action is used for GET, POST, postbacks.
In VB and C# there are "properties", and are used by many, much to the disgust of purists I've heard, and there are things in Ruby like 5.times and .each, .to_i etc.
And you have operator overloading, multiple inheritance, virtual functions in C++, certain combinations of which could drive anyone nuts.

I mean to say that there are so many paradigms and ways in which things are done that it seems odd that nobody has tried the particular combination that I mentioned.

As for me, my reason is that it is short and cleaner to read the code.
Am I very wrong, slightly wrong, is this just odd and so not used, or what else?

If I still decide to stay correct, I could use car.speed() and car.setSpeed(55).
Is that wrong in any way (just omitting the "get" )?

Thanks for any explanations.

+8  A: 

IMHO the C# style of having properties as syntatic sugar for get and set methods is the most expressive.

Otávio Décio
For those unfamiliar, here are examples of using C# properties: s = car.Speed; car.Speed=55;
JeffH
Being able to do myObject.ThingsCount++ is not only syntactic sugar but also way more readable than a myObject.setThingsCount(MyObject.getThingsCount() + 1);
herzmeister der welten
@herzmeister der welten - without a doubt.
Otávio Décio
Python also supports properties as syntactic sugar for get and set (and del) methods.
Edward Loper
As do many other languages ( recent JavaScript versions, C++ if you're clever, common-lisp to name a few off hand. )
Pete Kirkham
@herz Good point
AaronLS
+3  A: 

FYI, Objective-C uses car.speed() and car.setSpeed(55) (except in a different syntax, [car speed] and [car setSpeed:55].

It's all about convention.

KennyTM
+1  A: 

The groovy approach to properties is quite excellent IMHO, http://groovy.codehaus.org/Groovy+Beans

A: 

Apart from unambiguous clarity, why should we stick to: car.getSpeed() and car.setSpeed(55) when this could be used as well : car.speed() and car.speed(55)

Because in all languages I've encountered, car.speed() and car.speed(55) are the same in terms of syntax. Just looking at them like that, both could return a value, which isn't true for the latter if it was meant to be a setter.

Jon Seigel
+10  A: 

If I called car.speed(), I might think I am telling the car to speed, in other words to increase speed and break the speed limit. It is not clearly a getter.

Some languages allow you to declare const objects, and then restrict you to only calling functions that do not modify the data of the object. So it is necessary to have seperate functions for modification and read operations. While you could use overloads on paramaters to have two functions, I think it would be confusing.

Also, when you say it is clearer to read, I can argue that I have to do a look ahead to understand how to read it:

car.speed()

I read "car speed..." and then I see there is no number so I revise and think "get car speed".

car.getSpeed()

I read "for this car, get speed"

car.setSpeed(55)

I read "for this car, set speed to 55"

It seems you have basically cited other features of the language as being confusing, and then used that as a defense for making getters/setters more confusing? It almost sounds like are admitting that what you have proposed is more confusing. These features are sometimes confusing because of how general purpose they are. Sometimes abstractions can be more confusing, but in the end they often serve the purpose of being more reusable. I think if you wanted to argue in favor of speed() and speed(55), you'd want to show how that can enable new possibilities for the programmer.

On the other hand, C# does have something like what you describe, since properties behave differently as a getter or setter depending on the context in what they are used:

Console.WriteLine(car.Speed); //getter

car.Speed = 55 //setter

But while it is a single property, there are two seperate sections of code for implementing the getting and setting, and it is clear that this is a getter/setter and not a function speed, because they omit the () for properties. So car.speed() is clearly a function, and car.speed is clearly a property getter.

AaronLS
**"If I called car.speed(), I might think I am telling the car to speed, in other words to increase speed and break the speed limit. It is not clearly a getter."** - That explains it prefectly. It is indeed confusing if you think of it that way. My aim was to be "short and sweet", but if it can be misunderstood half the time, it's a *new problem, not a solution* :-)
namespaceform
If I see "car.speed()" I see a method. If I see "int speed = car.speed()" I see a getter.
Chad
To clarify, it will be very difficult to keep track of which member name sounds like a method name, and to prevent that the price to pay is just a "get", which is quite fine.
namespaceform
This answer is specific to the word "speed", because it is both a verb and a noun. Replace "speed" which is something that is just a noun, and it no longer applies.
Terry Mahaffey
@Terry, the example I gave was to illustrative of the problems that could result from the proposed naming convention. Why do we often use camel case in case sensitive languages, and underscores in case insensitive languages? There are several reasons, but one is because without those conventions, identifiers like "therapist" might be confused with "The Rapist". So my answer was not specific to the word "speed". That was simply an example of the type of problem that is avoided by the convention of prepending get* and set*. You have to learn to generalize examples or you miss the point.
AaronLS
+1  A: 

The final benchmarks of your code should be this:

  1. Does it work correctly?
  2. Is it easy to fix if it breaks?
  3. Is it easy to add new features in the future?
  4. Is it easy for someone else to come in and fix/enhance it?

If those 4 points are covered, I can't imagine why anybody would have a problem with it. Most of the "Best Practices" are generally geared towards achieving those 4 points.

Use whichever style works for you, just be consistent about it, and you should be fine.

Bryan Ross
+1  A: 

This is just a matter of convention. In Smalltalk, it's done the way you suggest and I don't recall ever hearing anybody complain about it. Getting the car's speed is car speed, and setting the car's speed to 55 is car speed:55.

If I were to venture a guess, I would say the reason this style didn't catch on is because of the two lines down which object-oriented programming have come to us: C++ and Objective-C. In C++ (even more so early in its history), methods are very closely related to C functions, and C functions are conventionally named along the lines of setWhatever() and do not have overloading for different numbers of arguments, so that general style of naming was kept. Objective-C was largely preserved by NeXT (which later became Apple), and NeXT tended to favor verbosity in their APIs and especially to distinguish between different kinds of methods — if you're doing anything but just accessing a property, NeXT wanted a verb to make it clear. So that became the convention in Cocoa, which is the de facto standard library for Objective-C these days.

Chuck
+4  A: 

I prefer active objects which encapsulate operations rather than getters and setters, so you get a semantically richer objects.

For example, although an ADT rather than a business object, even the vector in C++ has paired functions:

size_type capacity() const // how many elements space is reserved for in the vector  
void reserve(size_type n)  // ensure space is reserved for at least n elements 

and

void push_back ( const T& ) // inserts an element at the end
size_type size () const     // the number of elements in the vector

If you drive a car, you can set the accelerator, clutch, brakes and gear selection, but you don't set the speed. You can read the speed off the speedometer. It's relatively rare to want both a setter and a getter on an object with behaviour.

Pete Kirkham
**+1** That's a nice way of designing. Also, it does not give any unnecessary freedom to the calling code and is probably a more secure way of designing an API or classes that others just need to use, rather than modify.
namespaceform
+1  A: 

It's convention Java has a convention of getters and setters C# has properties, python has public fields and JavaScript frameworks tend to use field() to get and field(value) to set

RHicke
+3  A: 

There is no right answer, it's a matter of style, and ultimately it does not matter. Spend your brain cycles elsewhere.

FWIW I prefer the class.noun() for the getter, and class.verb() for the setter. Sometimes the verb is just setNoun(), but other times not. It depends on the noun. For example:

my_vector.size() 

returns the size, and

my_vector.resize(some_size) 

changes the size.

Terry Mahaffey
A: 

What if you intend to call the setter but forget to put in the argument? The code is valid, so the compiler doesn't complain, and it doesn't throw an immediate runtime error; it's a silent bug.

Justin
Not if you use TDD. Things like that would be caught immediately.
Chad
A: 

.() means it's a verb. no () means it's a noun.

   car.Speed = 50;
   x = car.Speed
   car.Speed.set(30)
   car.setProperty("Speed",30)

but

   car.Speed()

implies command to exceed speed limit.

SF.