As I have had it explained, the open/close principle states that once written code should not be modified (aside from bug fixes). But if my business rules change shouldn't I modify the code implementing those changes? I suspect I'm not understanding something about how the principle because it doesn't make sense to me.
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
This is probably the hardest of the solid principles to explain. Let me try. Imagine you wrote an Invoice class that works perfectly and has no bugs. It makes a PDF of an invoice.
Then someone says they want an HTML invoice with links in it. You don't change any code in Invoice to satisfy this request. Instead, you make another class, HTMLInvoice, that does what they now want. You leverage inheritance so that you don't have to write a lot of duplicate code in HTMLInvoice.
Old code that was using the old Invoice isn't broken or really affected in any way. The new code can use HTMLInvoice. (If you also do Liskov Substitutability, the L of solid, you can give HTMLInvoice instances to existing code that's expecting Invoice instances.) Everyone lives happily ever after.
Invoice is closed to modification, open to extension. And you have to write Invoice properly in advance for this to work, btw.
Have you read the The Open-Closed Principle article by Uncle Bob's pals at ObjectMentor? I think it's one of the better explanations out there.
The answer by Kate Gregory is very good, but consider a different situation where a new requirement can be satisfied by a relatively small change in the existing
In my understanding, OCP reflects the reality of the 80's and early 90's, where projects often did not even use version control, much less had automated regression tests or the benefit of sophisticated refactoring tools. OCP was an attempt to avoid the risk of breaking code that had been manually tested and put into production. Today, we have better ways to manage the risk of breaking working software (namely, version control systems, TDD and automated testing, and refactoring tools).
Personally I think this principle should be taken with a pinch of salt. Code is organic, businesses change and code changes according to the needs of a business as time goes on.
I find it very difficult to get my head around the fact that abstraction is key. What if the abstraction was originally wrong? What if the business function has changed significantly?
This principle essentially ensures that ORIGINAL intentions and behavior of a design must never change. That probably works for those who have public API's and their clients have trouble keeping up with new releases, and some other edge-cases. However, if a company owns ALL the code, then I challenge this principle.
Having good test coverage of your code should make refactoring your code base a breeze. It means that it's okay to get stuff wrong - your tests will help guide you to a better design.
Saying that, if there aren't any tests, then this principle is sound.