Bean of the Devil: Why Getters, Setters and Such are Evil

I felt like I'd already gotten this rant out of my system, but every time I come across the object oriented wreckage that the Java Bean and it's decendents have wrought, I get all heated up. The problem is, simply stated, that the getters and setters that get used for things like system boundaries -- Hibernate for persistence, Spring for dependency injection, Java Beans for UI components -- end up being misused for things that break basic OO principles.

How do these pernicious little getters and setters undermine OO? Let me count the ways.

  1. Encapsulation: the detailed implementation of an object is hidden from the rest of the system. Yes, yes, 99.99999% of all getters and setters are just fronting a private field and that's bad enough, but this is more about the getters, pulling data out of the object and doing things with it outside the object. They leak out, bit by bit, until you repeat yourself all over the place with slightly different manipulations of the data. Before you know it, you are looking at a siloed procedural applications that spurred the invention of OO in the first place.
  2. Polymorphism: one type can substituted for another. If your implementation is out there flapping in the breeze, it's hard to swap types. Even if you do, the application of polymorphism is usually pretty weak. Leaking implementation into the collaborating classes really ties your hands.
  3. High Cohesion: responsibilities of an object are strongly related and focused. If you pull information out of objects and deal with it in the collaborating objects, the cohesion is going to be progressively more diffuse.
  4. Low Coupling: low dependencies between classes, low impact of changes in a class on other classes and high reuse potential. This is a killer. Again, you have your implementation info spread all over the countryside like in a procedural application. You change the implementation and you are in for a mega refactoring.
  5. Information Expert: the responsibility goes to the object with all the relevant information. When you leak data into the collaborating classes, how can you identify the information expert?

There's more, of course, but the worst part is that in a system with getters and setters, the rot gets worse the longer the system is under development. A little enhancement can be done so easily by pulling an integer here, a string there and doing a little dance in a method without arranging the collaboration of necessary classes. You need to refactor and refactor to stem the tide. It is a problem of your own making that costs you time and budget.

So, think twice before you expose everything with getters and setters. I would argue that they be the exception and not the rule. A rare sprinking to season the system boundaries.