开发者

Why stick to get-set and not car.speed() and car.speed(55) respectively?

开发者 https://www.devze.com 2022-12-16 08:16 出处:网络
Apart from unambiguous clarity, why should we stick to: car.getSpeed() and car.setSpeed(55) when this could be used as well :

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.


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.


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


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.


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.


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.


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


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.


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.


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


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.


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.


.() 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消