Open-Closed Principle (OCP) – Let’s make it easy to understand
January 2, 2023 3 min read

What is OCP?
The open-closed principle is a software design principle that states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. This means that you should be able to add new functionality to a software entity without changing its existing code.
Here are a few real-world examples of the Open-Closed Principle with example code blocks (Javascript)
Let’s say we have a Shape class with a calculateArea method that calculates the area of the shape. We want to add a new shape, Circle, to our application. One way to do this would be to modify the Shape class to include a new method for calculating the area of a circle. However, this would violate the open-closed principle, because we would need to modify the existing Shape class in order to add the new functionality.
Instead, we can follow the open-closed principle by creating a new Circle class that extends the Shape class and implements its own version of the calculateArea method. This way, we can add the new Circle class to our application without modifying the existing Shape class.
class Shape {
calculateArea() {
// Calculate the area of the shape
}
}
class Circle extends Shape {
calculateArea() {
// Calculate the area of the circle
}
}
In this example, the Shape class is closed for modification, because we do not need to change its code in order to add the new Circle class. However, it is open for extension, because we can extend it by creating a new subclass that adds the desired functionality.
Let’s say we have a shopping cart application that calculates the total price of an order. The price of an order is determined by the base price of the items in the order and any applicable discounts.
We can implement this by creating a PriceCalculator class with a calculateTotal method that takes an array of items and a discount as arguments, and returns the total price of the order.
To follow the open-closed principle, we can create an Item class with a price property and a Discount class with a calculateDiscount method that calculates the discount for a given order.
class Item {
constructor(price) {
this.price = price;
}
}
class Discount {
calculateDiscount(items) {
// Calculate the discount for the given items
}
}
class PriceCalculator {
calculateTotal(items, discount) {
let total = 0;
for (let item of items) {
total += item.price;
}
return total - discount.calculateDiscount(items);
}
}
In this example, the PriceCalculator class is closed for modification, because we do not need to change its code in order to add new types of discounts. It is open for extension, because we can add new discounts by creating a new subclass of Discount and implementing the calculateDiscount method.
For example, we can create a PercentageDiscount class that calculates a discount based on a percentage of the total price:
class PercentageDiscount extends Discount {
constructor(percentage) {
super();
this.percentage = percentage;
}
calculateDiscount(items) {
let total = 0;
for (let item of items) {
total += item.price;
}
return total * this.percentage;
}
}
We can then use the PercentageDiscount class to calculate discounts in the PriceCalculator:
const calculator = new PriceCalculator();
const discount = new PercentageDiscount(0.1); // 10% discount
const items = [new Item(100), new Item(50), new Item(75)];
const total = calculator.calculateTotal(items, discount); // 225
In this solid principle series we have already discussed about the Single responsibility principle.
On next article we can check what is Liskov Substitution Principle.


