C# Object-Oriented Design – Is Rule 9 of Object Calisthenics Workable in Real Life?

cdesignobject-oriented

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?

Best Answer

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?