TDD vs Open-Closed Principle – Do They Contradict?

object-orientedopen-closed-principlesolidtdd

My understanding of the TDD methodology is that (failing) test cases are written promptly after finalizing the requirements.

My understanding of the open-closed principle (in the context of OOP) is to structure the class hierarchy so that any new features involve writing new code instead of modifying old code.

Those two strike me as contradicting. Shouldn't instead the process be more like

  1. clear up requirements
  2. take a long walk away from the computer
  3. design a public api with minimal implementation (e.g. throw NotImplemented)
  4. implement all requirements as tests, make sure they all fail
  5. don't touch the dummy implementation. Inherit the interface by another class, which turns all tests green?

Best Answer

It’s not contradictory, it’s complementary:

  • TDD is about writing tests to formalize and verify requirements. But it’s not about finalized user requirements: it’s about currently known design requirements. These translate/ transform some aspects of the user requirements in a way that makes sense in your design, and more specially take into account the distribution of responsibilities between your components.

  • OCP is about shaping your design in a way not to reinvent the wheel, but also not to break things that already work well. It allows you to specialize class, and benefit from the existing tests, and write new tests only for the specialized parts. (here I say specialization to mean extension).

So there is a synergy between the two that allows to quicker reach a stable and robust design:

  • OCP means not only clean design but also fewer tests to verify the same requirements
  • TDD will reveal weaknesses of the current design early, which could suggest need for refactoring
  • refactoring allows you to improve OCP if it wasn’t well thought initially.

This approach is therefore completely compatible with incremental or evolving user requirements, which will translate to new design requirements and refacotring.

For your API:

  • you can of course take a long walk and develop it mentally, challenging yourself, alone in your mind.
  • But you can as well develop it with TDD and OCP, using for example mocks and test doubles, to collaboratively, with your team, converge together to a very robust design.

It’s a matter of project size. The team simply has more brainpower than any individual that composes it and a team is not efficient in long abstract discussions in a long walk.

Related Topic