6

I've recently been reading about Object Calisthenics and I'm stuck on Rule 9.

My typical approach to code (I'm a C# .NET developer) is to model data as POCO classes which only exist to represent data schemas. Inevitably this means a set of properties exposed with getters and setters. These classes implement few, or more often no, methods. They are dumb objects and typically exist at a low level in my solution architecture. They have a singular responsibility: to model structured data e.g. a database table row.

Where I need logical functions, I'll introduce these as dedicated service classes in a business (or service) layer. These classes also observe the single-responsibility principle by each addressing a specific business requirement. For example, I may have a Customer class, and a CustomerRepository class charged with reading and writing to a persistent data store. This CustomerRepository will implement an IRepository contract to ensure I can inject it as a dependency, mock it in tests etc.

With this pattern, inevitably my Customer must expose its properties via getters and setters ("ejecting its own guts straight in your face"!) so that the repository can map it to a database table or whatever.

So my question is, why would a devotee of object calisthenics see this as so wrong? In all the examples I've seen, the authors keep properties private and introduce logical functions directly to the class which in my view breaks single responsibility, and could potentially lead to vast, unwieldy, untestable classes.

So, is Rule 9 really workable in real life? In one of the few detailed explanations I've found the author appears to argue against himself by defining an Account class, making the Balance private then introducing methods like Withdraw to encapsulate not just the property but any logic that works with that property. Fine, but what if the business requirement needs the programmer to write the account balance to a UI? How can Rule 9 be observed in that case?

9
  • 11
    Honestly, these "Object Calisthenics" rules seem pretty dumb if not dangerous. They build on sensible ideas, but turns them into hard rules without context, which in many cases will make code worse rather than better. I say forget you ever read about those rules, you will be happier in the long run. Read some quality texts instead.
    – JacquesB
    Commented Oct 2, 2017 at 17:38
  • 3
    @JacquesB Exactly. +1 Many of his principals are good, or rather have good reasoning behind them, but highly contextual. They cannot be applied nearly as universally as he implies. Commented Oct 2, 2017 at 17:40
  • 1
    see Discuss this ${blog}
    – gnat
    Commented Oct 2, 2017 at 17:42
  • 1
    @BenAaronson 's answer to this question is very good, prbly the best explanation I've seen. softwareengineering.stackexchange.com/questions/284215/… Commented Oct 2, 2017 at 19:20
  • 5
    This post says that "Object Calisthenics are programming exercises". It sounds like these rules aren't intended to be used "in real life"; they're intended as something that you do on the side, in order to learn something. If you try writing a side project where you follow these rules 100%, it'll teach you about how these rules can be beneficial, as well as how these rules can be harmful. (A rotation quaternion should be implemented as a class with four fields; breaking that into multiple classes is thoroughly pointless.) Commented Oct 2, 2017 at 21:43

2 Answers 2

6

His #9 principal is incorrect. Objects need getters and setters to be used in most real life applications. However, they should be used as little as possible.

Displaying the properties of an objects to an end user will need getters.

Allowing an end user to edit an objects properties will need setters.

A persistence layer will need getters and setters to save the object to disk and read it again.

A builder will need setters.

A better rule would be:

Other logical entities within the domain layer should not use another entity's getters and setters if it can be practically avoided

Now, there are some work-arounds to avoid using getters and setters in the above exceptions, but they are overly complex for most situations.


Your approach to object design has its own problems, and is the other extreme. You are basically doing functional programming in an OO language without proper functional facilities. However, that is a topic for another discussion.


Please see Ben's answer, it is great: How do you avoid getters and setters?

8
  • 2
    Thank you. Good to know my cynicism was warranted. I know my approach isn't ideal; my skills are pretty rusty which is my main motivation for researching these more modern trends. Commented Oct 2, 2017 at 18:40
  • @TomTroughton As was said in comments, please ignore that article. It is not that it is wrong, just that it is not expressed properly or with enough context to be useful. Commented Oct 2, 2017 at 18:47
  • 1
    @TomTroughton check this out, this is a better explanation. The article you mentioned is taking a lot of previous knowledge and expressing it in a way that makes it seem wrong :D martinfowler.com/bliki/GetterEradicator.html Commented Oct 2, 2017 at 18:51
  • On the whole I see value in most of those rules. As a set of principles aimed at keeping code clean and easy to read, they have some value. But some more then others. And Rule 9, to me, is daft! Commented Oct 2, 2017 at 18:55
  • 3
    I disagree with your assertion that this is "incorrect". The purpose of this exercise is to experience how the design changes if you impose a particular set of restrictions. Obviously, restricting your design to use no setters will change the design, so the rule works as intended, no? Commented Oct 2, 2017 at 22:21
3

From the link you provided:

In this case, you could keep the getScore() as you may want to display it somewhere on the UI, but keep in mind that setters should not be allowed.

So, in your example where the account balance would be shown on a UI, the getBalance() would be appropriate to keep.

Given your current model of writing POCO classes, you may not be able to reconcile the two. You may need to modify your design a bit to accommodate the lack of setters. Or, just realize what the spirit of Rule 9 is, and that is to prevent any object from wrecking your object. Given that your class only exists to map info from the DB, this seems to be a marginal concern.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.