Hacker News new | ask | show | jobs
by 0x445442 2620 days ago
Objects are meant to have a life cycle in which the state should only be changed by the object itself. Setters violate this idea by allowing the sender of the message direct control over the state of the object.

A simplistic example: account.deposit(100) may directly add 100 to the account's balance and a subsequent call to account.balance() may answer 100 more than when account.deposit(100) was called. But those details are up to that instance of the account not the sender of those messages. The sender should not be able to mutate account.balance directly, whether it be via direct access to the field or through the proxy of a setter.

2 comments

Well... a setter is the object changing its own state. That's why the setter has to be a member function.

I would say instead that an object shouldn't have setters or getters for any members unless really necessary. And by "necessary", I don't mean "it makes it easier to write code that treats the object as a struct". I mean "setting this field really is an action that this object has to expose to the external world in order to function properly". And not even "necessary" because I coded myself into a corner and that's the easiest way out I see. It needs to be necessary at the design level, not at the code level.

It depends, most of the time is better to have separate functions that transform your data rather than have methods and state conflated together. But obviously it depends from the context.
Yeah there are no hard and fast rules but a lot of time transformations can be in the object as well. If I need a function to transform Foo to Bar I could just as easily send a toBar() message to an instance of Foo.
I think c# really got the best of both worlds with extensions methods, where you can actually define functions that act on a object but are separated from the actual class definition. I still think that pure functions and especially higher kinded types are better probably, although I have no direct experience with Haskell type classes, scala implicits and ocaml modules..