Your company sells temperature sensors and software for it for many years. For the last 5 years there we produced only indoor sensors.
Yesterday your boss came around and told you, that you’ll now sell also outdoor sensors.
There is a class that feeds the gui with the average temperature of multiple sensors. You’re assigned the extend the average temperature class, which look quite messy after your change:
Before your change it simply took a List<IndoorTemperatureSensor> and it had only one for loop. But look at this – feels like we’re missing something…..
Make it Open OCP conform
Suddenly you remember the open closed principle:
SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION, BUT CLOSED FOR MODIFICATION.(The Open-Closed Principle, Robert C. Martin, The C++ Report)
That sounds odd, how can we build something that is closed for modification, but open for extension?
Abstraction is the key!
Because the AvgTemperatureReader is wired against the implementation “IndoorTemperatueSensor” we had to modify it to make work with our new outdoor sensor implementation.
The refactored solution uses an interface that provides access to the last read temperature. The abstract class removes code that would be duplicated in both sensor classes.
Look how simple the implementation of the AvgTemperatureReader looks like again:
The OCP is in my opinion a key concept of object oriented design. Applied correctly it supports building software where changes don’t cascade through large parts of your codebase. This is not easy, but deep knowledge of the domain and can help to build in the necessary abstractions.
The full example is avaible in my GitHub repository.