- Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. (http://www.objectmentor.com/resources/articles/ocp.pdf)
first coined it in the first edition of ObjectOrientedSoftwareConstruction
- A class should be open for extension, but closed for modification.
In other words, (in an ideal world...) you should never need to change existing code or classes: All new functionality can be added by adding new subclasses or methods, or by reusing existing code through delegation.
This prevents you from introducing new bugs in existing code. If you never change it, you can't break it. It also prevents you from fixing existing bugs in existing code, if taken to the extreme.
One of the PrinciplesOfObjectOrientedDesign
I consider this "a nice idea" and "a laudable goal", but elusive in practice: I change my abstractions too often. Also, if you do any amount of YouArentGonnaNeedIt
, you'll have no choice but to change existing code when you refactor. -- JeffGrigg
It seems to be another way of saying: estimate the future ChangePatterns, and build your software based on that profile. The hard part is predicting the future. I've gotten into the habit of giving a probability estimate for a given change and when I come to a trade-off fork in the road, select the path that fits the probability profile. However, it is easy to get it wrong. Plus, different developers give wildly different estimates. The short way of saying this is, OpenClosedPrinciple cannot work well without a good crystal ball. It is sort of like saying, "Stocks are easy, all you have to do is pick the right stock and you can be rich." It's a "tease" principle without teeth. --top
If, however, you consider DoTheSimplestThingThatCouldPossiblyWork
, you may come to the conclusion that minimizing the impact of changing your code is a simplifying force. The fact that we practice RefactorMercilessly
does not mean that we can't have code structures that promote extensibility without modification. Indeed, creating such structures should be one of the goals of refactoring.
for one of the techniques that is useful to meet the OpenClosedPrinciple
I find myself often amending the OCP as follows:
- A class should be open for extension and parameterization, but closed for modification.
That's not to say that all classes should be generic (templates in C++); it just serves to explicitly remind me that subclassing isn't the only class extension technique. There is also parameterization (and let's not forget composition too). Actually, this helps me more when trying to define flexible processes (for the tools I write to enact/facilitate) moreso than code. -- BradAppleton
I moved some Xp-centric criticism to OpenClosedPrincipleAndXp. What follows was a comment to that but seems more useful here. -- DaveHarris
I think that OCP might be a better metric than it is a rule. The more a class is reused, the more stable it is. The more stable it is, the safer it is to depend on it. The more a class is to be reused, the more important it becomes that it adhere to the OCP.
This is the point of two other principles: DependencyInversionPrinciple and StableAbstractionsPrinciple -- RobertCecilMartin 10-2-99
XP has shown us that there are many classes that can be altered frequently, at low expense, and to the benefit of the overall quality of the program. There is no need for these classes to follow the OCP, indeed adding otherwise unneeded code to do so is probably detrimental. However, those who have developed libraries, component based software, and software frameworks have shown that there is a tremendous value in having some classes that never change. These classes benefit greatly from the OCP.
Consider GUI code. The widgets that the GUI displays are generally highly reusable as a result there are many, many applications that rely on them and a change in the slightest nuance of their behavior could introduce bugs into any number of applications. It is therefore highly desirable to alter the behavior of these classes for a particular use through a process of extension rather than direct change. The code that makes direct use of the widgets, however, is highly application specific and is also most prone to requirements changes. The classes in this code are very unlikely to be reused. The code for their behavior ought to be written in a manner that is very clear and very easy to change directly. The OCP has virtually no value in these classes. -- PhilGoodwin
provides a good countercase to this: "Entities are not to be multiplied beyond necessity".
- When your hierarchy is My_Class->Shim->Hack->Bodge->Object then that's three extra layers of cruft filling up space and cycles.
- With bugs-per-line as a constant, more code == more bugs.
- The more inheritance, the more fragility upon a refactoring of a deeply-nested superclass.
- The more classes, the harder one has to work to grok what is going on.
''It seems to me you misunderstood "extension" in this context to mean "using inheritance", whereas what is actually meant is "adding/changing behaviour".
s an effective substitute for OpenClosedPrinciple
? That is, the equivalent rule, that permits RefactorMercilessly
, is NeverSubtractUnitTests?
? Or, rather, RefactorMercilessly
provides all the benefits of OCP, without the arrogance?
How does NeverSubtractUnitTests? affect the OpenClosedPrinciple? I see the two as unrelated concepts and my conception of NeverSubtractUnitTests? is a BadThing.
Can the discussion be summarized like this?
- The OpenClosedPrinciple is irrelevant or maybe harmful for seldom referenced classes.
- The more a class is used, the more the OpenClosedPrinciple applies.
Regarding Robert�s mentioning of the StableAbstractionsPrinciple
the principle would be rather:
- An interface should be open for extension, but closed for modification.
The book examples given of this principle seem to be rigged to only show changes that go "with the grain" of the example's partitioning. For example, they are always adding new geometry shapes and never new operations to existing shapes, nor changing the representation/interface of shapes. In other words, EvidenceByBestCaseScenario
"Evidence" of what???
Another way of saying this is that they give biased change-scenarios to promote their vision of OpenClosedPrinciple
Re: "Replacing a conditional with polymorphism permits more refactors, it permits the Open Closed Principle [definition]?, and it helps new behaviors emerge."
This is a hotly contested issue, but I don't remember the wiki topic names off the top of my head. Perhaps PolymorphismLimits
Also see StableAbstractionsPrinciple
. Of course the entire codebase is not usually "closed" with all new development by subclassing. But stable code can be more closed, and new code more open.
I would change this to say, "The more places an interface is used, the harder it is to change." It's perfectly doable to change it, but you must be aware of the cost. If 30 other functions are calling into a function, then you must check all 30 of them to make sure they will be able to handle a change in that one function.
See also: DeltaIsolation