Hacker News new | ask | show | jobs
by lacampbell 3535 days ago
I really don't understand why people love properties so much. Getters and setters are elements of bad style to me - like global variables or gotos. A language like Java (or indeed C#) - specifically designed for huge teams and enterprise programs - shouldn't provide syntax sugar for writing getters and setters.
2 comments

"I really don't understand why people love properties", followed by "Getters and setters are elements of bad style".

So you don't like either of the following:

  myObject.name = "Ben";
  myObject.setName("Ben");
What alternative would you suggest then?
Probably a rethink of the design. Why are you creating an object, then mutating its name from client code?

The whole point of an object is that client code shouldn't be concerned with such details as maintaining the state of each internal field. Try and think of an object as a single thing you send high level messages to you, instead of a struct, or a bag, or a hashtable.

What would a high level message for changing the name of some object look like, if not setName(newName)?
Calls to mutate state, such as changing the name field, should be rare. I don't see the value in adding syntactic sugar to make it easier to mutate state.
"Calls to mutate state, such as changing the name field, should be rare."

Says who?

For example, there is a business requirement that we know the on-hand quantity of some item in the warehouse.

It's a busy warehouse, and we keep picking that item for delivery, and replenishing it from our suppliers.

So, the quantity of the item keeps mutating.

How do you propose to deal with the above? Tell the warehouse people that they should only do their thing "rarely"? Seriously.

He means you'd call `increment(25)` to say you've got 25 more, or `employee.suspend()` instead of `employee.setAccess(SUSPENDED); employee.setPay(0); employee.setBenefits(NONE);`
a guess, but i'd wager "rare" here meant the code should in the main prefer immutable data structures (etc), not that the invocations per unit time of a particular method should be low.
Something like obj.rename(newName). This might seem like a trivial change, but the underlying idea is that we're no longer dealing with a setter only affecting one particular field, but an abstract message that may affect arbitrary internal state.
It would probably look exactly like setName(newName).

For me a better question is - why is the name being changed? What high level goal are you trying to accomplish that truly needs you to to directly mutate internal fields, after the object has already been created? Could the object - or system of objects - have been designed with a higher level interface, so that the outside world didn't have to concern itself with such things?

Things change?

Consider a trivial to-do list. You can click on the 'completed' checkbox. So the 'completed' field has chaged.

Or, you can say ooops I mistyped the label. So you change the label.

Is there anything wrong with that?

I guess not. Sometimes the cleanest thing to do is to just mutate a field - particularly for GUI objects.

I don't know if it's worth the overhead of having unthinking developers writing { get; set } for every field in every class because it makes things "easier".

Let's say I have an object representing a file in the file system, and I'm writing a file browser. I give the user the ability to rename the file.
I would say that at that point, it ceases to be a simple setter method (or set property). It's not a simple case of mutating some element of a data structure of filenames as strings. There'd be some validation and error handling involved. It's a perfectly valid high level message to send a file object.

As an aside, I'd probably make a method called "rename" that does this, as opposed to something like "setName".

I agree that setter properties are often a code smell, but getter properties are nice for calculated fields. As a very simple example, consider the following (C#):

  class Circle
  {
    public Circle(int radius) { Radius = radius; }
    public int Radius { get; }
    public int Diameter => Radius * 2;
  }
Diameter is a nice example of a getter property. However you could change radius to simply

    public int Radius;
I think you mean

    public final int radius;