An Open/Closed Principle kata
In one of our weekly book clubs, we worked on an Open/Closed Principle kata.
What's the OCP? The Open/Closed Principle, as proposed by Bertrand Meyer, says that systems should be open for extension, but closed for the modification of existing components. This notion commonly maps to the addition of new code to implement a new requirement, tied with the minimal modifications of existing code. For example, adding a new class without touching existing source file apart from some configuration.
The related Kata turns the OCP dial up to eleven, and requires you to implement a series of requirements in a strictly OCP way; it's not that code cannot be modified, but refactoring steps where it is extended must be separated from extension steps where new classes are added to the codebase.
Here are some links giving some examples of the process:
Given the unfamiliarity of the some of the team with the principle, we picked up a very simple problem: FizzBuzz*. However, it is not trivial to develop it by following OCP by the book*link repository; by the end of the 4 Pomodoros we had completed the main text and added a new requirement (42 is the Answer, not BuzzBang).
One thing that saves much time in this kind of exercises is to start with predefined scenarios (1st requirement: number itself; 2nd requirement: 3 is Buzz; and so on). Only show the current requirement, bring it to completion, and go to the next; unless of course you're exercising in splitting requirements...
The process must be followed, even blindly, to get a nice workout from this exercise; this is the point of a kata, and you should be a Nazi in avoiding violating the constraints that make the exercise difficult (for the duration of this exercise alone). Tell them their code will be thrown away at the end of the session, not put into production, and that exercising at the maximum viable effort is just for their benefit.
The protocol to follow is:
- read the new requirement and understand it.
- Add a new test for it, so that you now have N test and only 1 of them is failing.
- Refactor at will, but at any time only N - 1 tests must be green, and the new one must still be failing ("refactoring" move).
- Add new code and/or modify Factory classes that setup the system as a graph of objects or closures (as your only "new code" move).
- Show a green bar.
If you can't complete the "new code" move, come back to the refactoring step and repeat it differently. The constraints are:
- In the "refactoring" move there should still be N-1 tests passing and the new one failing (the form changes but not its function, to put it into Alexander's terms.)
- In the "new code" move nothing outside of Factories can be modified, while of course new classes can be added at will.
The first benefit of exercising on single principles and patterns is that you are then able to talk about OCP during daily work, within your team. Naming things is one of the first steps in mastering them. You can say to a colleague, ""You should first refactor the X package before adding functionality B, since it is a variation over functionality A that it was developed for. But first make it extensible, remember OCP?"
A side effect is that you can target solutions that follow this method and stimulate them during pair programming. Both participants need to be aware of the roads that can be followed to get at a solution together.
Finally, OCP-like solutions where new requirements are added only by adding code (and without adding duplication) are certainly in my list of code perfumes* (to be cherished, as the opposite of smells to be removed).
Working strictly and iteratively in the two OCP phases for a couple of hours doesn't mean this is always the right way to face a programming problem. However, when you're training your quadriceps, you don't suddenly go off cycling and come back every few minutes (at least the brain does not have muscles that you rotate in a single Pomodoro.) So no excuses for going off track: you can train other muscles and movements, as important as these, but at another time.
The OCP contraints are also a nice alternative for the usual kata on prime numbers or bowling, or to execute katas without a goal. One possible and frequent output of katas is that you end up with very dense 3 lines of code, that will not accept a new requirements even if menaced with a shotgun.
The purpose of those exercises is to show incremental development at work in microslices, but the OCP one forces the development of some architectural skill instead of working on a single, monolithic class.