A getter-less world
I found this posting (and this response) interesting, for presenting the following case:
John Nolan, gave his developers a challenge: write OO code with no getters. Whenever possible, tell another object to do something rather than ask. In the process of doing this, they noticed that their code became supple and easy to change.
This idea was most famously explored in Allen Holub's oldie-but-goodie "Why getter and setter methods are evil".
I wanted to explore this, not the why, but the how. How could I write code this way? Would it be any good?
Imagine a scenario. A Vet (as in veterinarian) object must give a Cat object an injection of medicine. If the cat is younger than four years old, the dosage must be halved.
Some pseudo-code to represent this might look like this:
vet.AdministerShot( Cat cat, String med, float dose ) {
if( cat.Age < 4 ) {
cat.SetMedicatedState( med, dose / 2 ) {
} else {
cat.SetMedicatedState( med, dose ) {
}
}
Cat.Age is a getter here, and Cat.SetMedicatedState a
setter. Can we re-design this to lose these public accessors? I worked out
this solution:
vet.AdministerShot( Cat cat, String med, float dose ) {
DoseRule rule = new YoungCatRule();
cat.AcceptShot( med, dose, rule );
}
// Now, in class Cat
void AcceptShot(String med, float dose, DoseRule rule) {
float actual = rule.Adjust(dose, _age);
_medicationState.Add( med, actual );
}
We did it! What was the cost?
- A new class family, DoseRule. Could be awkward, depending on the context, but not a big sacrifice.
- The cat is now responsible for receiving the shot, moreso than the vet is responsible for administering it. This seems wrong to me (especially being a cat owner).
- The cat is aware of its age, and the vet is not. I find this troubling.
And what did we gain? We adhered to the no-accessor rule. Supposedly this is easier to test, and to write mock objects for, but I don't see it.
In conclusion, this mental exercise was successful in hiding its state, but it feels awkward and academic. The resulting code seems less natural, no easier to maintain, and no easier to read. On top of that, I would be unable to explain the benefits to my colleagues. As interesting as the thought process is, I won't be re-factoring my code bases to this standard any time soon.