Update: Mark has a point - Using "TOOP" and "TOOD" are catchier acronyms - I've changed them accordingly.
I think it's time that Object Oriented Design\Programming got a little face lift.
We live in interesting times, where quality and the quest for testability and continuous integration are starting to sprout all over the development world.
It's in these times that one needs to think about one simple fact - in many ways, pure object oriented design does not go well hand in hand with the notion of testable design. I wrote about a classic example of this in this post - FxCop is removing Testability features in favor of object oriented pureness.
here are some examples for this dissonance in which OOP\OOD usually says "hide" while Testable design guidelines dictate "Expose":
- OOD: Do not expose any private members or methods that are not needed by the developer using your API .
- Testable: Find a way to expose or replace private instances of objects using interfaces, injection patterns, public setters and more.
- OOD: Seal classes to inheritance by default unless you explicitly mean for others to extend them
- Testable: Don't seal by default (unless it's a security risk) so that others can reuse your code and override what they need in their tests.
- OOD: only make methods virtual explicitly (in java methods are virtual by default which is an interesting strategy which I very much like) when you want others to override them.
- Testable: when possible, make virtual the default so that inheritors can override them to break any dependencies found in their tests.
- OOD: Use singletons to make sure only one instance exists. do not allow anyone to touch that private instance.
- Testable: Allow others to replace Singleton instances to break any dependencies in their tests.
- OOD: make types private or internal by default unless you want to expose them specifically.
- Testable: Think about and expose types that you know would help the testability of your API
- OOD: Don't add unnecessary APIs
- Testable: Add special APIs like methods, interfaces and types especially for testability purposes. These are necessary.
What if we added the word "Testability" into the OOD paradigm?
"Testable Object Oriented Design: TOOD"
"Testable Object Oriented Programming: TOOP"
This paradigm would take into account the testability factor of each design, and will allow for specific design issues to be solved with testability as the winner. In many ways you can't have a truly testable design without the proper (and heavy) use of some of the object oriented principles (polymorphism is as ubiquitous in testable designs as Falafel in Israel - everywhere you look there's another corner offering it). Combining the values of both paradigms will lead to a better and more solid future for software quality for all of us.
But where do we start?