So I recently made some major refactorings to my code. One of the main things I tried to do was split out my classes into data objects and worker objects. This was inspired, among other things, by this section of Clean Code:
Hybrids
This confusion sometimes leads to unfortunate hybrid data structures that are half object and half data structure. They have functions that do significant things, and they also have either public variables or public accessors and mutators that, for all intents and purposes, make the private variables public, tempting other external functions to use those variables the way a procedural program would use a data structure.
Such hybrids make it hard to add new functions but also make it hard to add new data structures. They are the worst of both worlds. Avoid creating them. They are indicative of a muddled design whose authors are unsure of - or worse, ignorant of - whether they need protection from functions or types.
Recently I was looking at the code to one of my worker objects (that happens to implement the Visitor Pattern) and saw this:
@Override
public void visit(MarketTrade trade) {
this.data.handleTrade(trade);
updateRun(trade);
}
private void updateRun(MarketTrade newTrade) {
if(this.data.getLastAggressor() != newTrade.getAggressor()) {
this.data.setRunLength(0);
this.data.setLastAggressor(newTrade.getAggressor());
}
this.data.setRunLength(this.data.getRunLength() + newTrade.getLots());
}
I immediately said to myself "feature envy! this logic should be in the Data
class - specifically in the handleTrade
method. handleTrade
and updateRun
should always happen together". But then I thought "the data class is just a public
data structure, if I start doing that, then it will be come a Hybrid Object!"
What's better and why? How do you decide which to do?