Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good examples of OCP in open source libraries [closed]

There has been a lot of discussion on the subject of “Open Closed Principle” on stackoverflow. It seems however, that generally a more relaxed interpretation of the principle is prevalent, so for example the Eclipse is open for modification through plug-ins.

According to strict OCP, you should modify the original code only to fix bugs, not to add new behaviour.

Are there any good examples of strict interpretation of OCP in public or OS libraries, where you can observe evolution of a feature through OCP: there is a class Foo with method bar() and than there is a FooDoingAlsoX with foo2() method in the next version of the library, where original class has been extended where original code was not modified.

EDIT: According to Robert C. Martin: “The binary executable version of the module, whether a linkable library, a DLL, or a Java .jar remain untouched”*. I never see libraries kept closed, in practice new behaviour is added to a library and new version published. According to OCP, new behaviour belongs to new binary module.

*Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin

like image 817
Dan Avatar asked Aug 28 '11 17:08

Dan


2 Answers

The OCP principle says that a class shall be open for extension but closed for changes. The key to achieve this is abstraction. If you also read the DIP principle you'll find out that abstractions should not depend upon details, but details should depend upon abstractions. In your example you have details in your interface (two specific methods bar() and foo2()). To fully implement OCP you shall try to avoid such details (and for example try to move them behind the abstraction and instead have one general foo-method with different implementations).

For example take a look at this interface in SolrNet: https://github.com/mausch/SolrNet/blob/master/SolrNet/ISolrCommand.cs This is a general command that that only tell that a command can be executed, it doesn't give more details than that.

The details instead lies in the implementations of the interface: https://github.com/mausch/SolrNet/tree/master/SolrNet/Commands

As you see you can add as many commands as you wish without changing the implementation of any other class. The specific implementations can hereby be considered closed for modifications, but the interface allow us to extend the functionality with new commands, and is hereby open for extension.

(SolrNet isn't extraordinarily in anyway, I just used examples from this project because I happen to have it in my browser when I read this post, almost all good coded OO projects make use of the OCP principle in one way or another)

EDIT: If you want examples of this on the binary level you can for example take a look at nopCommerce (http://nopcommerce.codeplex.com/releases/view/69081) where you for example can add your own shipping providers, payment providers or exchange rate providers without even touching the original DLL by implementing a set of interfaces. And again, it is not something extraordinarily with nopCommerce, it was just the first project that came into mind because I used it a couple of days ago ;)

OCP is not not a principle that shall only be used on binary level though, good OOD uses OCP, not everywhere, but in all levels where it is suitable ;) "Strict" OCP on the binary level is not always suitable and would add an extra level of complexity if you used it in every single situation, it is mostly interesting in situations when you want to change implementation in runtime or when you want to let external developers be able to extend your interfaces. You shall always keep the OCP principle in mind when you desing your interfaces, but you shall not see it as a law but a principle that shall be used in the correct situations.

I guess you refer to Agile Principles, Patterns and Practices when you quote Robert C Martin, if so, also read the conclusion in the same chapter where he says about the same thing as I did above. If you for example read his book Clean Code he gives a more gradate explanation of the OCP principle and I would say the quote above is a bit unfortunate since it can let people think that you shall always put new code in new DLL:s, JAR:s or libs when the truth is that you shall always consider the context.

I think your rather should take a look at Martins more up to date whitepaper about OCP http://objectmentor.com/resources/articles/ocp.pdf (which he also refer to in his later book Clean Code), there he never refer to separate binaries, rather he refer to "classes, modules, functions". I think this proves that Martin means not just binary extension when he speaks about OCP but also extensions of classes and functions, so binary extension is not more "strict" than the class extension in my first example.

like image 137
Martin Odhelius Avatar answered Nov 15 '22 10:11

Martin Odhelius


I am not aware of really good examples but I think that there might be a reason for the more "relaxed interpretation" (for example here on SO):

To fully realize the OCP principle in a real world project you need to do the coupling via lean Interfaces (see ISP and DIP for this) and Dependency Injection (either property or constructor based)... otherwise you are really fast either stuck or need to resort to the "relaxed interpretation"...

some interesting links in this regard:

  • http://www.oodesign.com/open-close-principle.html
  • http://javaboutique.internet.com/tutorials/JavaOO/index2.html
  • http://joelabrahamsson.com/entry/the-open-closed-principle-a-real-world-example
  • http://joelabrahamsson.com/entry/simple-example-of-the-open-closed-principle
like image 33
Yahia Avatar answered Nov 15 '22 10:11

Yahia