<p>The Open/Closed Principle states that software entities (classes, modules, etc.) should be open for extension, but closed for modification. What does this mean, and why is it an important principle of good object-oriented design?</p>

[{'answer_id': 59021, 'author': 'DaveK', 'author_id': 4244, 'author_profile': 'https://Stackoverflow.com/users/4244', 'pm_score': 0, 'selected': False, 'text': '<p>This means that the OO software should be built upon, but not changed intrinsically. This is good because it ensures reliable, predictable performance from the base classes. </p>\n'}, {'answer_id': 59032, 'author': 'jodonnell', 'author_id': 4223, 'author_profile': 'https://Stackoverflow.com/users/4223', 'pm_score': 3, 'selected': False, 'text': "<p>It's the answer to the fragile base class problem, which says that seemingly innocent modifications to base classes may have unintended consequences to inheritors that depended on the previous behavior.  So you have to be careful to encapsulate what you don't want relied upon so that the derived classes will obey the contracts defined by the base class.  And once inheritors exist, you have to be <em>really</em> careful with what you change in the base class.</p>\n"}, {'answer_id': 59034, 'author': 'Lars A. Brekken', 'author_id': 6120, 'author_profile': 'https://Stackoverflow.com/users/6120', 'pm_score': 2, 'selected': False, 'text': '<p>The principle means that it should easy to add new functionality without having to change existing, stable, and tested functionality, saving both time and money. </p>\n\n<p>Often, polymorhism, for instance using interfaces, is a good tool for achieving this.</p>\n'}, {'answer_id': 59064, 'author': 'aku', 'author_id': 1196, 'author_profile': 'https://Stackoverflow.com/users/1196', 'pm_score': 6, 'selected': False, 'text': "<p>It means that you should put new code in new classes/modules. Existing code should be modified only for bug fixing. New classes can reuse existing code via inheritance.</p>\n<p>Open/closed principle is intended to mitigate risk when introducing new functionality. Since you don't modify existing code you can be assured that it wouldn't be broken. It reduces maintenance cost and increases product stability.</p>\n"}, {'answer_id': 59065, 'author': 'Russell Leggett', 'author_id': 2828, 'author_profile': 'https://Stackoverflow.com/users/2828', 'pm_score': 4, 'selected': False, 'text': "<p>More specifically than DaveK, it usually means that if you want to add additional functionality, or change the functionality of a class, create a subclass instead of changing the original. This way, anyone using the parent class does not have to worry about it changing later on. Basically, it's all about backwards compatibility.</p>\n\n<p>Another really important principle of object-oriented design is loose coupling through a method interface. If the change you want to make does not affect the existing interface, it really is pretty safe to change. For example, to make an algorithm more efficient. Object-oriented principles need to be tempered by common sense too :)</p>\n"}, {'answer_id': 59427, 'author': 'Troy DeMonbreun', 'author_id': 5487, 'author_profile': 'https://Stackoverflow.com/users/5487', 'pm_score': 6, 'selected': True, 'text': '<p>Specifically, it is about a "Holy Grail" of design in OOP of making an entity extensible enough (through its individual design or through its participation in the architecture) to support future unforseen changes without rewriting its code (and sometimes even without re-compiling **).</p>\n\n<p>Some ways to do this include Polymorphism/Inheritance, Composition, Inversion of Control (a.k.a. DIP), Aspect-Oriented Programming, Patterns such as Strategy, Visitor, Template Method, and many other principles, patterns, and techniques of OOAD.</p>\n\n<p>** See the 6 "package principles", <a href="http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" rel="noreferrer">REP, CCP, CRP, ADP, SDP, SAP</a></p>\n'}, {'answer_id': 294410, 'author': 'quamrana', 'author_id': 4834, 'author_profile': 'https://Stackoverflow.com/users/4834', 'pm_score': 2, 'selected': False, 'text': "<p>An additional rule of thumb for conforming to OCP is to make base classes abstract with respect to functionality provided by derived classes.  Or as Scott Meyers says 'Make Non-leaf classes abstract'.  </p>\n\n<p>This means having unimplemented methods in the base class and only implement these methods in classes which themselves have no sub classes.  Then the client of the base class cannot rely on a particular implementation in the base class since there is none.</p>\n"}, {'answer_id': 349631, 'author': 'sharkin', 'author_id': 7891, 'author_profile': 'https://Stackoverflow.com/users/7891', 'pm_score': 1, 'selected': False, 'text': '<p>I just want to emphasize that "Open/Closed", even though being obviously useful in OO programming, is a healthy method to use in all aspects of development. For instance, in my own experience it\'s a great painkiller to use "Open/Closed" as much as possible when working with plain C.</p>\n\n<p>/Robert</p>\n'}, {'answer_id': 10659236, 'author': 'Andrew Gray', 'author_id': 1404206, 'author_profile': 'https://Stackoverflow.com/users/1404206', 'pm_score': 0, 'selected': False, 'text': '<p>I was recently given an additional idea of what this principle entails: that the Open-Closed Principle describes at once a way of writing code, as well as an end-result of writing code in a resilient way.</p>\n\n<p>I like to think of Open/Closed split up in two closely-related parts:</p>\n\n<ul>\n<li>Code that is <strong>Open</strong> to change can either change its behavior to correctly handle its inputs, or requires minimum modification to provide for new usage scenarios.</li>\n<li>Code that is <strong>Closed</strong> for modification does not require much if any human intervention to handle new usage scenarios.  The need simply does not exist.</li>\n</ul>\n\n<p>Thus, code that exhibits Open/Closed behavior (or, if you prefer, fulfills the Open/Closed Principle) requires minimal or no modification in response to usage scenarios beyond what it was originally built for.</p>\n\n<p>As far as implementation is concerned?  I find that the commonly-stated interpretation, "Open/Closed refers to code being polymorphic!" to be at best an incomplete statement.   Polymorphism in code is one tool to achieve this sort of behavior; Inheritance, Implementation...really, every object-oriented design principle is necessary to write code that is resilient in the way implied by this principle.</p>\n'}, {'answer_id': 41296104, 'author': 'Rajesh Dixit', 'author_id': 6011301, 'author_profile': 'https://Stackoverflow.com/users/6011301', 'pm_score': 0, 'selected': False, 'text': '<p>In Design principle, SOLID – the "O" in "SOLID" stands for the open/closed principle.</p>\n\n<p>Open Closed principle is a design principle which says that a class, modules and functions should be open for extension but closed for modification.</p>\n\n<p>This principle states that the design and writing of the code should be done in a way that new functionality should be added with minimum changes in the existing code (tested code). The design should be done in a way to allow the adding of new functionality as new classes, keeping as much as possible existing code unchanged.</p>\n\n<p>Benefit of Open Closed Design Principle:</p>\n\n<ol>\n<li>Application will be more robust because we are not changing already tested class.</li>\n<li>Flexible because we can easily accommodate new requirements.</li>\n<li>Easy to test and less error prone.</li>\n</ol>\n\n<p>My blog post on this:</p>\n\n<p><a href="http://javaexplorer03.blogspot.in/2016/12/open-closed-design-principle.html" rel="nofollow noreferrer">http://javaexplorer03.blogspot.in/2016/12/open-closed-design-principle.html</a></p>\n'}, {'answer_id': 44913685, 'author': 'maysara', 'author_id': 5503714, 'author_profile': 'https://Stackoverflow.com/users/5503714', 'pm_score': 3, 'selected': False, 'text': "<blockquote>\n  <p>Software entities should be open for extension but closed for modification</p>\n</blockquote>\n\n<p>That means any class or module should be written in a way that it can be used as is, can be extended, but neve modified</p>\n\n<h2>Bad Example in Javascript</h2>\n\n<pre><code>var juiceTypes = ['Mango','Apple','Lemon'];\nfunction juiceMaker(type){\n    if(juiceTypes.indexOf(type)!=-1)\n        console.log('Here is your juice, Have a nice day');\n    else\n        console.log('sorry, Error happned');\n}\n\nexports.makeJuice = juiceMaker;\n</code></pre>\n\n<p>Now if you want to add Another Juice type, you have to edit the module itself, By this way, we are breaking OCP .</p>\n\n<h2>Good Example in Javascript</h2>\n\n<pre><code>var juiceTypes = [];\nfunction juiceMaker(type){\n    if(juiceTypes.indexOf(type)!=-1)\n        console.log('Here is your juice, Have a nice day');\n    else\n        console.log('sorry, Error happned');\n}\nfunction addType(typeName){\n    if(juiceTypes.indexOf(typeName)==-1)\n        juiceTypes.push(typeName);\n}\nfunction removeType(typeName){\n  let index = juiceTypes.indexOf(typeName)\n    if(index!==-1)\n        juiceTypes.splice(index,1);\n}\n\nexports.makeJuice = juiceMaker;\nexports.addType = addType;\nexports.removeType = removeType;\n</code></pre>\n\n<p>Now, you can add new juice types from outside the module without editing the same module.</p>\n"}, {'answer_id': 61270467, 'author': 'Sumanth Varada', 'author_id': 4044987, 'author_profile': 'https://Stackoverflow.com/users/4044987', 'pm_score': 3, 'selected': False, 'text': "<p>Open Closed Principle is very important in <strong>object oriented programming</strong> and it's one of the <strong>SOLID</strong> principles.</p>\n\n<blockquote>\n  <p><em>As per this, a class should be open for extension and closed for\n  modification. Let us understand why.</em></p>\n</blockquote>\n\n<pre><code>class Rectangle {\n    public int width;\n    public int lenth;\n}\n\nclass Circle {\n    public int radius;\n}\n\nclass AreaService {\n    public int areaForRectangle(Rectangle rectangle) {\n        return rectangle.width * rectangle.lenth;\n    }\n\n    public int areaForCircle(Circle circle) {\n        return (22 / 7) * circle.radius * circle.radius;\n    }\n}\n</code></pre>\n\n<blockquote>\n  <p><em>If you look at the above design, we can clearly observe that it's not\n  following <strong>Open/Closed Principle</strong>. Whenever there is a new\n  shape(Tiangle, Square etc.), <strong>AreaService</strong> has to be modified.</em></p>\n</blockquote>\n\n<p><strong>With Open/Closed Principle:</strong></p>\n\n<pre><code>interface Shape{\n    int area();\n}\n\nclass Rectangle implements Shape{\n    public int width;\n    public int lenth;\n\n    @Override\n    public int area() {\n        return lenth * width;\n    }\n}\n\nclass Cirle implements Shape{\n    public int radius;\n\n    @Override\n    public int area() {\n        return (22/7) * radius * radius;\n    }\n}\n\nclass AreaService {\n    int area(Shape shape) {\n        return shape.area();\n    }\n}\n</code></pre>\n\n<blockquote>\n  <p><em>Whenever there is new shape like Triangle, Square etc. you can easily\n  accommodate the new shapes without modifying existing classes. With\n  this design, we can ensure that existing code doesn't impact.</em></p>\n</blockquote>\n"}, {'answer_id': 64537644, 'author': 'Yogesh Umesh Vaity', 'author_id': 5925259, 'author_profile': 'https://Stackoverflow.com/users/5925259', 'pm_score': 3, 'selected': False, 'text': "<p>Let's break down the question in three parts to make it easier to understand the various concepts.</p>\n<hr />\n<h2>Reasoning Behind Open-Closed Principle</h2>\n<p>Consider an example in the code below. Different vehicles are serviced in a different manner. So, we have different classes for <code>Bike</code> and <code>Car</code> because the strategy to service a <code>Bike</code> is different from the strategy to service a <code>Car</code>. The <code>Garage</code> class accepts various kinds of vehicles for servicing.</p>\n<p><strong>Problem of Rigidity</strong></p>\n<p>Observe the code and see how the <code>Garage</code> class shows the signs of rigidity when it comes to introducing a new functionality:</p>\n<pre><code>class Bike {\n    public void service() {\n        System.out.println(&quot;Bike servicing strategy performed.&quot;);\n    }\n}\n\nclass Car {\n    public void service() {\n        System.out.println(&quot;Car servicing strategy performed.&quot;);\n    }\n}\n\nclass Garage {\n    public void serviceBike(Bike bike) {\n        bike.service();\n    }\n\n    public void serviceCar(Car car) {\n        car.service();\n    }\n}\n</code></pre>\n<p>As you may have noticed, whenever some new vehicle like <code>Truck</code> or <code>Bus</code> is to be serviced, the <code>Garage</code> will need to be modified to define some new methods like <code>serviceTruck()</code> and <code>serviceBus()</code>. That means the <code>Garage</code> class must know every possible vehicle like <code>Bike</code>, <code>Car</code>, <code>Bus</code>, <code>Truck</code> and so on. So, it violates the open-closed principle by being open for modification. Also it's not open for extension because to extend the new functionality, we need to modify the class.</p>\n<hr />\n<h2>Meaning Behind Open-Closed Principle</h2>\n<p><strong>Abstraction</strong></p>\n<p>To solve the problem of rigidity in the code above we can use the open-closed principle. That means we need to make the <code>Garage</code> class dumb by taking away the implementation details of servicing of every vehicle that it knows. In other words we should abstract the implementation details of the servicing strategy for each concrete type like <code>Bike</code> and <code>Car</code>.</p>\n<p>To abstract the implementation details of the servicing strategies for various types of vehicles we use an <code>interface</code> called <code>Vehicle</code> and have an abstract method <code>service()</code> in it.</p>\n<p><strong>Polymorphism</strong></p>\n<p>At the same time, we also want the <code>Garage</code> class to accept <em>many forms</em> of the vehicle, like <code>Bus</code>, <code>Truck</code> and so on, not just <code>Bike</code> and <code>Car</code>. To do that, the open-closed principle uses <em>polymorphism</em> (many forms).</p>\n<p>For the <code>Garage</code> class to accept many forms of the <code>Vehicle</code>, we change the signature of its method to <code>service(Vehicle vehicle) { }</code> to accept the interface <code>Vehicle</code> instead of the actual implementation like <code>Bike</code>, <code>Car</code> etc. We also remove the multiple methods from the class as just one method will accept many forms.</p>\n<pre><code>interface Vehicle {\n    void service();\n}\n\nclass Bike implements Vehicle {\n    @Override\n    public void service() {\n        System.out.println(&quot;Bike servicing strategy performed.&quot;);\n    }\n}\n\nclass Car implements Vehicle {\n    @Override\n    public void service() {\n        System.out.println(&quot;Car servicing strategy performed.&quot;);\n    }\n}\n\nclass Garage {\n    public void service(Vehicle vehicle) {\n        vehicle.service();\n    }\n}\n</code></pre>\n<hr />\n<h2>Importance of Open-Closed Principle</h2>\n<p><strong>Closed for modification</strong></p>\n<p>As you can see in the code above, now the <code>Garage</code> class has become closed for modification because now it doesn't know about the implementation details of servicing strategies for various types of vehicles and can accept any type of new <code>Vehicle</code>. We just have to extend the new vehicle from the <code>Vehicle</code> interface and send it to the <code>Garage</code>. That's it! We don't need to change any code in the <code>Garage</code> class.</p>\n<p>Another entity that's closed for modification is our <code>Vehicle</code> interface.\nWe don't have to change the interface to extend the functionality of our software.</p>\n<p><strong>Open for extension</strong></p>\n<p>The <code>Garage</code> class now becomes open for extension in the context that it will support the new types of <code>Vehicle</code>, without the need for modifying.</p>\n<p>Our <code>Vehicle</code> interface is open for extension because to introduce any new vehicle, we can extend from the <code>Vehicle</code> interface and provide a new implementation with a strategy for servicing that particular vehicle.</p>\n<p><strong>Strategy Design Pattern</strong></p>\n<p>Did you notice that I used the word <em>strategy</em> multiple times? That's because this is also an example of the Strategy Design Pattern. We can implement different strategies for servicing different types of <code>Vehicle</code>s by extending it. For example, servicing a <code>Truck</code> has a different strategy from the strategy of servicing a <code>Bus</code>. So we implement these strategies inside the different derived classes.</p>\n<p>The strategy pattern allows our software to be flexible as the requirements change over time. Whenever the client changes their strategy, just derive a new class for it and provide it to the existing component, no need to change other stuff! The open-closed principle plays an important role in implementing this pattern.</p>\n<hr />\n<p>That's it! Hope that helps.</p>\n"}, {'answer_id': 68566748, 'author': 'Ramakrishna Joshi', 'author_id': 8956093, 'author_profile': 'https://Stackoverflow.com/users/8956093', 'pm_score': 2, 'selected': False, 'text': "<p>Purpose of the <strong>O</strong>pen closed Principle in S<strong>O</strong>LID Principles is to</p>\n<ol>\n<li>reduce the cost of a business change requirement.</li>\n<li>reduce testing of existing code.</li>\n</ol>\n<blockquote>\n<p>Open Closed Principle states that we should try not to alter existing\ncode while adding new functionalities. It basically means that\nexisting code should be open for extension and closed for\nmodification(unless there is a bug in existing code). Altering existing code while adding new functionalities requires existing features to be tested again.</p>\n</blockquote>\n<p>Let me explain this by taking AppLogger util class.</p>\n<p>Let's say we have a requirement to log application wide errors to a online tool called Firebase. So we create below class and use it in 1000s of places to log API errors, out of memory errors etc.</p>\n<pre><code>open class AppLogger {\n\n    open fun logError(message: String) {\n        // reporting error to Firebase\n        FirebaseAnalytics.logException(message)\n    }\n}\n</code></pre>\n<p>Let's say after sometime, we add Payment Feature to the app and there is a new requirement which states that only for Payment related errors we have to use a new reporting tool called Instabug and also continue reporting errors to Firebase just like before for all features including Payment.</p>\n<p>Now we can achieve this by putting an if else condition inside our existing method</p>\n<pre><code>fun logError(message: String, origin: String) {\n    if (origin == &quot;Payment&quot;) {\n        //report to both Firebase and Instabug\n        FirebaseAnalytics.logException(message)\n        InstaBug.logException(message)\n    } else {\n        // otherwise report only to Firebase\n        FirebaseAnalytics.logException(message)\n    }\n}\n</code></pre>\n<p>Problem with this approach is that it violates <strong>S</strong>ingle Responsibility Principle which states that a method should do only one thing. Another way of putting it is <em>a method should have only one reason to change</em>. With this approach there are two reasons for this method to change (if &amp; else blocks).</p>\n<p>A better approach would be to create a new Logger class by inheriting the existing Logger class like below.</p>\n<pre><code>class InstaBugLogger : AppLogger() {\n\n    override fun logError(message: String) {\n        super.logError(message) // This uses AppLogger.logError to report to Firebase.\n        InstaBug.logException(message) //Reporting to Instabug\n    }\n}\n</code></pre>\n<p>Now all we have to do is use InstaBugLogger.logError() in Payment features to log errors to both Instabug and Firebase. This way we reduce/isolate the testing of new error reporting requirement to only Payment feature as code changes are done only in Payment Feature. The rest of the application features need not be tested as there are no code changes done to the existing Logger.</p>\n"}]
['https://Stackoverflow.com/questions/59016', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3012/']