7

I am not working yet, just studying and recently dealing with SOLID principles. I have read quite a lot about open closed principle but unfortunately most of the books and articles share the same examples. I do not understand the following: if the class should not be changed after it has been

  • 4
    This is a common misunderstanding of the OCP - it does not mean "don't change a class under all circumstances", it means "design a class with the right extension points, so you can avoid the necessity for changes". See also softwareengineering.stackexchange.com/questions/361977/… – Doc Brown Jan 24 '18 at 18:32
  • When you can version all of your code together, OCP is good advice but carries less weight. When you can't version all your code together (i.e. because the application, DLL's, or plug-ins are owned by multiple providers with separate release cycles) then OCP carries more weight because making modifications across boundaries is substantially more difficult. In short, it says think hard about your API designs, as once you have clients using them, they're harder to change. – Erik Eidt Jan 24 '18 at 19:34
3

But it does not address the issue if the base class implementation needs to change (for example a method that is implemented at the base class level). Why this principle does not address that?

The point of keeping it open to extension is to avoid needing to make that direct modification.

Directly modifying is always possible but can come with significant costs. The OCP asks you to start with a design that hopefully avoids the need for direct modification, and it's costs, as requirements change.

A design that allows some polymorphic replacement of the offending behavior means you don't have to touch the code you wish to change. You just write new code.

That means if you find you HAVE to change the base class implementation you've already failed to follow OCP. You should have used a design that would have allowed that implementation to be replaced with other code written somewhere else.

There are many ways to do this. Polymorphism comes in many forms. Inheritance, composition and delegation, wrappers, it goes on and on. Any of these can avoid seeing that base code implementation called.

If you write code that directly accesses this implementation in a way that gives no one any way to replace it with some other implementation then you violated OCP before the change. Don't do that unless you're either very sure that the implementation will never need to change or that you're willing to take on the costs of making direct modifications in the implementaion.

It's not that the principle doesn't address a need to directly change base class implementation. It expressly tells you to avoid creating a need to do that.

  • 2
    On reading this answer, I had a doubt. My suspicions were confirmed on reading this Wikipedia article: the "closed" part of OCP is intended, not to protect the private implementation of a class from modification, but to protect its public API, and the clients who use it. The "open" part of the OCP does not preclude changing the implementation of a class either; it says "make it possible to extend the behavior of a class without modifying the class." – Robert Harvey Jan 24 '18 at 18:11
  • 3
    I'm saying that OCP has mostly to do with the API of a class, and not its innards. – Robert Harvey Jan 24 '18 at 18:29
  • 1
    True. I suppose "preserve the invariants" is a better description of the proper strategy. Note that extending classes comes with its own costs, so you're really trading one set of costs for another, in exchange for preserving the invariants. – Robert Harvey Jan 24 '18 at 18:34
  • 1
    @RobertHarvey: my understanding of the OCP involves indeed no changes to the implementation of a class afterwards - a class follows the OCP (for a certain category of changes), when I can think of it as coming from a 3rd party vendor like MS who will never ever change it, but I can still reuse it in different scenarios by "extending" it, using the provided extension points. – Doc Brown Jan 24 '18 at 18:41
  • 1
    @EzoelaVacca: I think you're getting a bit ahead of yourself. All OCP really means is "allow classes to be extensible." Dependency Injection has its own set of goals. – Robert Harvey Jan 24 '18 at 19:03
3

In the real world sometimes changing requirements means changing modifying things, but there are ways to mitigate how often that happens. SOLID is a list of principles that sometimes compete with each other and its up to the developer to determine which are the most important for the situation at hand.

For changing algorithms a common solution is to use the strategy pattern to require the algorithm to be provided when the object is created at run time and therefore different objects can be used. This also is part of the dependency inversion principle. Lets use calculating grades as an example, there can be multiple ways to curve or not curve grades, so your class that calculates grades requires a function to provide that curve as part of its creation. This means you can have the same class calculate grades differently without modifying that class.

Another way to help keep classes closed is involved with the single responsibility principle, which also can help decide when a class need to be modified. If there is a change to the responsibility of a class it's very likely that you will need to modify it. if a class has multiple responsibilities its far more likely to need to be modified and have a greater chance of causing bugs because you are modifying multiple responsibilities at once. For calculating grades you can have a base class that only cares about the process of calculating the score, and extend with classes responsible for formatting that score as a letter, percentage, pass/fail, or something else.

Ideally the only reason a class should get modified is the requirements directly related to its responsibility change. Depending on the domain this may be constant or extremely rare.

0

A class is only supposed to be closed to modification. It's open to extension though.

So if your class has a method, AddOne, that adds one to a value, then AddOne should not one day be changed to add two to a value. That would be modification and the class is closed to that.

Instead, a new method, AddTwo is added, that handles that new algorithm. That's extension and the class is open to that.

The exception to the rule being if a bug is found in AddOne. Then its behaviour can be modified.

  • And what if the requirements changes? E.g. now the business requirements is to add two, instead of one. This is what I mean. This principle should be about accommodation for new requirements but the requirement could simply change something to work differently. Or a change in a complex calculation. – Ezoela Vacca Jan 24 '18 at 16:46
  • It's a principle; not a law. It's a useful principle to follow on a general basis, but if it makes sense to completely change a class due to business requirements, then modify it. :) – David Arno Jan 24 '18 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.