Encapsulation is considered by some to be the fundamental quality of object-oriented systems. That is, the qualities we look for are strongly related in various ways to encapsulate.
Quite often, encapsulation is considered as synonymous with “data hiding,” but this is too limited a definition. Encapsulation is the hiding of any aspect of one part of a system from other parts of the system. Data can (and should) be hidden, but you can also hide the aspects such as the following:
One benefit of studying design patterns is that they teach you how to encapsulate many things that you might not have thought could be encapsulated.
Anything that is hidden can be more safely changed, and so we seek to hide everything we can. The distinction between what we can hide and what we must reveal is also extremely helpful: Creating interfaces that expose only that which is needed makes those interfaces a lot more meaningful.
Valuing encapsulation helps with most of the code qualities. For example, it is easier to hide two concepts from one another when they are in separate, cohesive methods or classes than it is when they are lumped together. Another example is that properly encapsulating variation in behavior often improves the testability of a system.
We suggest that you encapsulate by policy and reveal by need. Adding encapsulation after the fact is always more difficult that removing it after the fact. So, if you start off by encapsulating everything you can and then later realize that a given thing needs to be visible in the system (if, for instance, it needs to be reusable to avoid redundancy) then you simply make it visible. If something has been visible from the beginning and then you realize it should not have been, trying to hide it later will likely involve re-designing other parts of the system that have become coupled to it. This can be a huge challenge.
Sometimes people object to encapsulating “too much” based on wanting to be able to “understand what’s going on.” This is similar to the objection found in cohesion and can be addressed in a similar way. For any given developer, an objection is there until it is overcome and then it is gone forever.
There is a more persistent obstacle to encapsulation: not seeing that something is unencapsulated. Everyone is trained to spot and eliminate magic numbers. Everyone can see a violation of data hiding.
Many things can be encapsulated and should be. A lot of things that can be encapsulated are not as obvious as, say, a duplicated string. For example, the method by which an object is created can be encapsulated from how it is used and always should.
Sometimes, no matter how experienced, you miss the repetition of some little algorithm or the redundancy of some little structure.
Fight time-released risk with time-released remediation. Odds are you already have missed stuff and will continue to do so throughout your career.
Some of the mistakes will never be noticed. There’s nothing you can do about that and, probably the cost of those mistakes is not very high.
You can do something about what you do notice: the unencapsulated concepts, relationships, etc. If the cost of encapsulating something changes over time, it will almost certainly be by going up. If you notice a lack of encapsulation and correct it immediately, you will keep the cost of fixing the problem low and increase the quality of your system at the same time.
The cheapest time to correct an error is the moment you find it.
Core Developer Skills Overview
- McConnell, Steve. Code Complete: A Practical Handbook of Software Construction. 1993.