“A software artifact should be open for extension but closed for modification.”
Extension, so this must be about inheritance? Sure enough, in Bertrand Meyer’s original incarnation, that was the case but hold on there!
Over the past 30 years, we’ve learned that inheritance is quite a tricky beast to tame, so we might not want to take that route right away.
What do we mean by preventing modification and allowing for extension? If you have to change reams of existing code every time you make a small alteration then you know there’s something wrong with your architecture — it isn’t closed for modification.
Rather than changing what’s already there, you should be able to build on top of a robust foundation through extension. Adding new features should ideally be easy and low risk.
Extension itself has more than one form. Firstly, you have the traditional mode of inheritance. This, as mentioned, comes with its own set of problems (discussed elsewhere).
Alternatively, you can inject additional behavior into high-level components. Interfaces are the perfect tool for extension through injection. They protect against modification by presenting a well-defined contract that controls change.
They then allow us to extend our software by providing and plugging in new implementations of this contract.
The use of interfaces here ensures a robust hierarchy where those important high-level components are protected from changes in lower-level ones. When that next feature request comes along you’ll be ready to slot it in without touching those precious existing functions.
Originally published at Better Programming
Top comments (0)