Blog
0

Open-Closed Principle

  • Pradyumn Sharma
  • July 25, 2017

Tags:

When you need to modify a class to change its behaviour, refactor it in such a manner that you don’t need to modify it again for the same reason.

 
The Open-Closed Principle (OCP) is the second of the five SOLID principles of object-oriented design. It states that:

Software entities (classes, modules, functions, etc) should be open for extension, but closed for modification.

 
What does this mean?

SOLID is an acronym for five important principles of object-oriented design:

  • Single Responsibility Principle (SRP)
  • Open-Closed Principle (OCP)
  • Liskov Substitution Principle (LSP)
  • Interface Segregation Principle (ISP)
  • Dependency Inversion Principle (DIP)

A full list of Robert Martin’s principles is available at:

http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

 
Let us first talk about classes. We know that, from time to time, as the requirements for a system change, we need to modify the code in one or more classes of the system.
The OCP suggests that we should be able to extend the behaviour of a class, without having to modify its code. How is that possible?
Let’s take an example: suppose we have a class called ‘BankLoan, which represents the behaviour of, and information about, a loan from a bank. One of its public methods is: getInterestForMonth:

1
2
3
public float getInterestForMonth () {
    return principal * interestRate / 12;
}

 
[Typically, there is another public method called getInterestForPartMonth (Date startDate, Date endDate), which is used only in the first and the last months of a loan, for computing the interest for the partial month. But we can ignore that method, at least for the time being.]

 
Simple stuff. The code has been tested, delivered to the customer, and put into production.
Now, some time later, our customer tells us that while for the long-term loans, the bank will continue to calculate interest for a month as above (1/12th of the annual interest amount), for short-term loans, say, for tenure of less than or equal to 91 days, they have decided to compute the interest based on the actual number of days in the month. So, for example, since March has more days than April, the interest charged to a borrower in the month of March will be proportionately more than the one in April.
This suddenly complicates things. What about February and leap years? In a leap year, February has 29 days out of 366 for the year, while in other years, it has 28 days out of 365. Our customer tells us that we have to account for leap years correctly. Thus, the interest that a borrower will pay for:

  • January in a leap year will be 31/366 of the full year’s interest
  • January in a non-leap year will be 31/365 of the full year’s interest
  • February in a leap year will be 29/366 of the full year’s interest
  • February in a non-leap year will be 28/365 of the full year’s interest

It turns out, that these are just some of the ways in which banks compute interest. There are other ways too.

  • Our current, simple implementation (1/12th of the annual interest for a month) is known as 30/360 in banking parlance.
  • The proposed, new requirement is known as actual/actual
  • And there are others, such as actual/365 fixed, in which the extra day of a leap year is ignored

(For a more detailed description of the above, and other methods of interest computation, please refer to this Wikipedia article.)
To summarize, our customer asks us to retain the 30/360 approach for long-term loans (more than 91 days), and actual/actual approach for short-term loans (less than or equal to 91 days).
We now realize that we must change the signature of the getInterestForMonth method. It will need to know the month and year for which the computation is to be done. Apart from this, the implementation will also depend on the tenure of the loan.
So a modification to the BankLoan class is inevitable. But can we use this as an opportunity to refactor the code in such a manner that if in the future, the bank asks us to incorporate some other interest computation approaches, such as actual/365 fixed, we would not have to modify the BankLoan class any further.
Essentially, what we need to do is to extract the variant part of the class (interest computation approach) away from it. One way to achieve this would be to have a separate class hierarchy, with a common interface, as shown in the diagram below:
 




 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class BankLoan {
    // …
    private float principal;
    private float interestRate;
    private int tenureInDays;
    private InterestStrategy interestStrategy;
    // …
    public float getInterestForMonth (int year, int month) {
        return interestStrategy.getInterestForMonth (this, year, month);
    }
    // …
}
interface InterestStrategy {
    public float getInterestForMonth (BankLoan loan, int year, int month);
    // …
}
class ThirtyByThreeSixtyInterestStrategy implements InterestStrategy {
    public float getInterestForMonth (BankLoan loan, int year, int month) {
        // …
    }
}
class ActualByActualInterestStrategy implements InterestStrategy {
    public float getInterestForMonth (BankLoan loan, int year, int month) {
        // …
    }
}

 
This refactoring may have been quite some work, and many client classes may have to be modified for this. But those would have had to be modified even if we had chosen not to separate the variant part from the BankLoan class.
But now, because of this update, our BankLoan class would no longer have to be modified if in the future, our customer asks us to add another interest computation approach, such as actual/365 fixed.
The BankLoan class is now open for extending its behaviour, while being closed for modification.
 
Closing Remarks
Applying the Open-Closed Principle makes it easier to subsequently extend the behavior of a class without having to modify its source code. The key to achieving this is to have a separate class hierarchy with an interface, in which we extract the variant behaviour(s) of the original class.
Of course, it would also have been possible to make BankLoan an abstract class, with getInterestForMonth as an abstract method, and have separate subclasses for each of the different interest computation strategies 619 roofing. But as we’ll see in another article later, using delegation to a class through an interface (as in our implementation) is usually a better approach than having subclasses.
We can see the OCP approach in many of the GoF design patterns, such as Strategy, State, Abstract Factory, and Bridge. All these patterns use delegation to another class through an interface.
However, two of the GoF design patterns — Template Method and Factory Method, can be seen to use the OCP approach using concrete subclasses for extracting variant behaviour from an abstract superclass.
Though the example presented in this article applies OCP to a class, we can similarly apply the OCP to other types of software entities, such as components.

24 responses to “Open-Closed Principle”

  1. prony bony says:

    lBleMb This is very interesting, You are a very skilled blogger. I ave joined your feed and look forward to seeking more of your great post. Also, I have shared your website in my social networks!

  2. here says:

    I think this is a real great post.Really thank you! Really Great.

  3. Very nice post. I just stumbled upon your weblog and wished to say that I ave really enjoyed browsing your blog posts. After all I all be subscribing to your rss feed and I hope you write again soon!

  4. Muchos Gracias for your blog post.Really looking forward to read more. Fantastic.

  5. That is very fascinating, You are a very professional blogger. I ave joined your rss feed and sit up for searching for more of your great post. Also, I have shared your web site in my social networks

  6. Thanks for sharing, this is a fantastic post. Keep writing.

  7. Our communities really need to deal with this.

  8. Your style is so unique compared to other people I ave read stuff from. I appreciate you for posting when you have the opportunity, Guess I all just book mark this page.

  9. I?d need to examine with you here. Which isn at one thing I usually do! I enjoy studying a submit that will make people think. Additionally, thanks for permitting me to remark!

  10. Keep up the great work , I read few posts on this internet site and I believe that your blog is rattling interesting and contains bands of great information.

  11. name says:

    Wonderful article! We are linking to this great

  12. Your style is really unique in comparison to other people I have read stuff from. Thanks for posting when you have the opportunity, Guess I will just bookmark this page.

  13. shopping so appаА аЂа•аА аЂаling. There are mаА аЂаny things which eveаА аБТ–y Internet shopper

  14. This is one awesome article post. Really Cool.

  15. sex toys says:

    Usually I don at read article on blogs, but I wish to say that this write-up very forced me to take a look at and do so! Your writing taste has been amazed me. Thanks, very nice article.

  16. sex toys says:

    Just wanna comment that you have a very decent website , I enjoy the layout it really stands out.

  17. lingerie says:

    Wonderful blog! I found it while searching on Yahoo

  18. lingerie nyc says:

    This very blog is without a doubt educating as well as amusing. I have picked helluva helpful tips out of this source. I ad love to come back every once in a while. Thanks a lot!

  19. nyc lingerie says:

    Thanks so much for the blog post.Really thank you! Awesome.

  20. nyc sex toys says:

    You, my friend, ROCK! I found just the info I already searched all over the place and just couldn at find it. What a great web-site.

  21. Wow, awesome blog layout! How long have you been blogging for? you make blogging look easy. The overall look of your web site is great, let alone the content!

  22. Just Browsing While I was browsing yesterday I saw a excellent article about

  23. We are a group of volunteers and opening a new scheme in our community.

  24. Dispensary says:

    Superb weblog here! Also your web site loads up quick! What host are you utilizing? Can I get your affiliate link to your host? I wish my internet site loaded up as rapidly as yours lol

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2017 Pragati Software Pvt. Ltd. All Rights Reserved.

Enquiry

Pragatisoftware