Let's say I am tasked with coding some kind of an RPG. This means that, for example, I'll want to track a Character
GameCharacter
and stats thereof, like intelligence, damage bonuses or hitpoints.
I'm positively scared that by the end of the project I may end up with handling with very a high number of fields - and for each I would have to make sure they follow a very similar set of constraint and behaviours (for example, I want them to be bounded between a min and a max; I want to be able to distinguish between a "base value" and a "temporary bonus"; I want to be able to increment and decrement both without going through a setters and getters). Suddenly, for every field I would need one (two?) getter and four setters and maybe a couple resetters too! Even for 10 fields that means a LOT of methods all alike, eek.
For DRYness I have started encapsulating the logic of messing with those stats in Field
classes, so that I could write code such as intelligence.applyBonus(10)
or hitpoints.get()
(which takes care the value returned is in range), etc. I have even gone to such a length to create classes to group those fields together, but that's not the point right now.
Now, I hit in this problem while "plugging" Field
into GameCharacter
: most Java textbooks say that each class should have private fields with public getters and setters. That sounds good in theory, and I've already built a whole class around an int
; however, the idea doesn't sound as solid when you find yourself calling a getter to get... a getter:
thisCharacter.getIntelligence().get() //eeek
I'd much rather access the field directly. Maybe it's my Python/VB [1] "background", but for me it is cleaner, clearer and more straightforward:
thisCharacter.intelligence.get()
The (theoretical) problem with public fields is that I'm giving up all control on it; for example at some other point in the codebase, by misfortune, the following might happen:
thisCharacter.intelligence = somethingThatReallyIsNull;
Sounds like a subtle bug... but... I mean, should I really worry about that? I for one never plan to assign the Field
directly [2], I have documented in the Javadoc that this is not something that should be done, but still I am new here so I'm a bit torn.
So I would like to hear what your take on this topic. Are the advantages of encapsulation so massive that I should go ahead and have getter getters and setter getters and so on... or should I take encapsulation in healthy measures and leave the Field
as a public
field?
[1] Yes, I know. I've been trying to forget. But we've just recently seen also a bit of C# and man, aren't properties sweet. Oh well.
[2] except in Constructors! And a getter won't save me from a faulty constructor.