SOLID – Open Closed Principle

Open Closed Principle (OCP) states that,

Software entities (Classes, modules, functions) should be OPEN for EXTENSION, CLOSED for MODIFICATION.

Lets try to reflect on the above statement- software entities once written shouldn’t be modified to add new functionality, instead one has to extend the same to add new functionality.

In other words you don’t touch the existing modules thereby not disturbing the existing functionality, instead you extend the modules to implement the new requirement. So your code is less rigid and fragile and also extensible.

OCP term was coined by Bertnard Meyer.

How can we confirm to OCP principle?

Its simple – Allow the modules (classes) to depend on the abstractions, there by new features can be added by creating new extensions of these abstractions.

Let me try to explain with an example:

Suppose you are writing a module to approve personal loans and before doing that you want to validate the personal information, code wise we can depict the situation as:

public class LoanApprovalHandler
{
  public void approveLoan(PersonalValidator validator)
  {
    if ( validator.isValid())
    {
      //Process the loan.
    }
  }
}
public class PersonalLoanValidator
{
  public boolean isValid()
  {
    //Validation logic
  }
}

So far so good. As you all know the requirements are never the same and now its required to approve vehicle loans, consumer goods loans and what not. So one approach to solve this requirement is to:

public class LoanApprovalHandler
{
  public void approvePersonalLoan (PersonalLoanValidator validator)
  {
    if ( validator.isValid())
    {
      //Process the loan.
    }
  }
  public void approveVehicleLoan (VehicleLoanValidator validator )
  {
    if ( validator.isValid())
    {
      //Process the loan.
    }
  }
  // Method for approving other loans.
}
public class PersonalLoanValidator
{
  public boolean isValid()
  {
    //Validation logic
  }
}
public class VehicleLoanValidator
{
  public boolean isValid()
  {
    //Validation logic
  }
}

We have edited the existing class to accomodate the new requirements- in the process we ended up changing the name of the existing method and also adding new methods for different types of loan approval. This clearly violates the OCP. Lets try to implement the requirement in a different way:

/**
 * Abstract Validator class
 * Extended to add different
 * validators for different loan type
 */
public abstract class Validator
{
  public boolean isValid();
}
/**
 * Personal loan validator
 */
public class PersonalLoanValidator
  extends Validator
{
  public boolean isValid()
  {
    //Validation logic.
  }
}
/*
 * Similarly any new type of validation can
 * be accommodated by creating a new subclass
 * of Validator
 */

Now using the above validators we can write a LoanApprovalHandler to use the Validator abstraction.

public class LoanApprovalHandler
{
  public void approveLoan(Validator validator)
  {
    if ( validator.isValid())
    {
      //Process the loan.
    }
  }
}

So to accommodate any type of loan validators we would just have create a subclass of Validator and then pass it to the approveLoan method. That way the class is CLOSED for modification but OPEN for extension.

Another example:

I was thinking of another hypothetical situation where the use of OCP principle can be of use. The situation is some thing like: “We maintain a list of students with their marks, unique identification(uid) and also name. Then we provide an option to get the percentage in the form of uid-percentage name value pairs.”

class Student
{
  String name;
  double percentage;
  int uid;
  public Student(String name, double percentage, int uid)
  {
    this.name = name;
    this.percentage = percentage;
    this.uid = uid;
  }
}

We collect the student list into a generic class:

class StudentBatch {
  private List<Student> studentList;
  public StudentBatch() {
    studentList = new ArrayList<Student>();
  }
  public void getSutdentMarkMap(Hashtable<Integer, Double> studentMarkMap) {
    if (studentMarkMap == null) {
      //Error
    } else {
      for (Student student : studentList) {
        studentMarkMap.put(student.uid, student.percentage);
      }
    }
  }
  /**
   * @param studentList the studentList to set
   */
  public void setStudentList(List<Student> studentList) {
    this.studentList = studentList;
  }
}

Suppose we need to maintain the order of elements in the Map by their insertion order, so we would have to write a new method to get the map in the insertion order and for that we would be using LinkedHashMap. Instead if the method- getStudentMarkMap() was dependent on the Map interface and not the Hashtable concrete implementation, we could have avoided changing the StudentBatch class and instead pass in an instance of LinkedHashMap.

public void getSutdentMarkMap(Map<Integer, Double> studentMarkMap) {
    if (studentMarkMap == null) {
      //Error
    } else {
      for (Student student : studentList) {
        studentMarkMap.put(student.uid, student.percentage);
      }
    }
  }

PS: I know that Hashtable is an obsolete collection and not encouraged to be use. But I thought this would make another useful example for OCP principle.

Some ways to keep your code closer to confirming OCP:

Making all member variables private so that the other parts of the code access them via the methods (getters) and not directly.
Avoiding typecasts at runtime- This makes the code fragile and dependent on the classes under consideration, which means any new class might require editing the method to accommodate the cast for the new class.

Really good article written by Robert Martin on OCP.

Reference: SOLID- Open Closed Principle from our JCG partner Mohamed Sanaulla at the “Experiences Unlimited” blog.

Related Articles :

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


two × 8 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close