Helpers, wrappers, and managers – when abstractions go bad
Object-oriented programming is a good thing, but it’s important not to get carried away. Some programmers believe more classes == more abstraction, and say things like “better wrap that in a class so it’s more abstract”. That’s a sure tip-off that someone’s been drinking too much OO Kool-Aid.
The concept of abstraction – building higher-level components out of lower-level ones – is the most important thing in programming. But lately I’ve been running across code like this:
public class ProductHelper {
private Product _product = null;
public ProductHelper () {
_product = null;
}
public ProductHelper (Product product) {
_product = product;
}
public void setProduct (Product product) {
_product = product;
}
public Product getProduct () {
return _product;
}
}
That’s not really abstraction, since ProductHelper is at the same abstraction level as the underlying Product class. It’s like building a kitchen table out of, well, another kitchen table.
It’s also not encapsulation. If all the instance variables in a class have getters and setters, you’re not really “hiding” anything.
Some programmers argue that it’s good to create Helper or Wrapper classes when you need to access classes not under your control – for example if the underlying classes are generated Web Service stubs. But that argument is misguided. Unless the Helper or Wrapper classes are truly at a higher level of abstraction (i.e. provide a simpler interface to the underlying functionality), any changes to the underlying classes will still require you to update the client code, plus you’ll have to update the Helper classes as well.
A good tipoff that a piece of code has too many non-abstract abstractions is when many of the classes (or namespaces) are called things like “Helper”, “Wrapper”, “Manager”, “Engine”, or other names that don’t really correspond to domain objects. That’s when it’s time to dump the Kool-Aid and start simplifying the class hierarchy.



April 3rd, 2006 at 1:18 pm
See also Jeff Atwood’s recent article on this point:
http://www.codinghorror.com/blog/archives/000553.html
November 2nd, 2006 at 11:27 pm
I guess my WrapperManagerEngine helper library is right out then.
Really, it takes a lot of hard work (even some philosophy) to get to a concise expression of a solution in the language of a particular problem domain. I think that the wrapper/manager/helper/engine/variant stuff is sometimes an indication that the author doesn’t quite have a grasp of the main problem. Their system doesn’t quite work the way they wanted it to, so they pile more and more epicycles on, hoping that it will converge to what they want. Eventually the real organizing principles are discovered — like Kepler’s laws of motion — and the epicycles vanish. But it’s always a hard slog until then.
As you hinted at with your “OO Kool-Aid” phrase, the epicycles that people plot can be much more subtle than pluggable log context manager engines. Have you seen this paper on financial contract combinators?
June 23rd, 2007 at 8:05 am
i use the helper/manager/engine thing as a crutch while figuring out a problem space. i’ve got a design going with most of the responsibilities assigned sensibly. but while implementing, i’ll hit some responsibility that doesn’t belong anywhere. to keep my momentum, i just plop the responsibility into a catchall helper/manager/engine and leave the cruft to work out later. typically commented with things like “not sure where else to put this.”
since it indicates something wrong, it is a reminder that i need to rethink the design and the factoring of responsbilities and, well, the naming of things.
there should be a code tool that goes through code and summarizes the number of helper/manager/engine/getter/setter classes. this way you can remind yourself, oh gotta refactor/rethink that piece …