Open/Closed Principle in JavaScript: Making Your Code More Flexible and Scalable

Post author: Adam VanBuskirk
Adam VanBuskirk
5/9/23 in
Tech
JavaScript

The Open/Closed Principle (OCP) is a fundamental principle of software design that states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. In other words, we should be able to add new functionality to our code without modifying the existing code. In this article, we’ll explore the OCP in JavaScript and provide an example of how it can be violated and then fixed. OCP is one of the principles of SOLID Design Principles.

Violation of the OCP

Let’s take a look at an example of a violation of the OCP:

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Circle {
  constructor(radius) {
    this.radius = radius;
  }

  getArea() {
    return Math.PI * Math.pow(this.radius, 2);
  }
}

class AreaCalculator {
  constructor(shapes = []) {
    this.shapes = shapes;
  }

  getTotalArea() {
    let totalArea = 0;
    this.shapes.forEach((shape) => {
      if (shape instanceof Rectangle) {
        totalArea += shape.getArea();
      } else if (shape instanceof Circle) {
        totalArea += shape.getArea();
      }
    });
    return totalArea;
  }
}

In the example above, we have a Rectangle and Circle class that calculate their respective areas, and an AreaCalculator class that calculates the total area of all shapes. The problem with this code is that if we want to add a new shape, such as a triangle, we need to modify the AreaCalculator class by adding another conditional statement. This violates the OCP, as the AreaCalculator class is not closed for modification.

Applying The OCP

To fix this violation of the OCP, we need to create an abstract Shape class that all shapes inherit from. Let’s see how this can be done:

class Shape {
  getArea() {}
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

class Circle extends Shape {
  constructor(radius) {
    super();
    this.radius = radius;
  }

  getArea() {
    return Math.PI * Math.pow(this.radius, 2);
  }
}

class AreaCalculator {
  constructor(shapes = []) {
    this.shapes = shapes;
  }

  getTotalArea() {
    let totalArea = 0;
    this.shapes.forEach((shape) => {
      totalArea += shape.getArea();
    });
    return totalArea;
  }
}

In this example, we have created an abstract Shape class that all shapes inherit from. The Shape class has a getArea method that is implemented by its subclasses. By doing this, we have made the AreaCalculator class closed for modification and open for extension. If we want to add a new shape, we just need to create a new class that inherits from the Shape class and implements the getArea method.

Conclusion

The Open/Closed Principle is a crucial principle in software design. By following this principle, we can create code that is more maintainable, flexible, and scalable. Violating this principle can lead to code that is difficult to modify and extend, and can cause problems down the road. By creating abstract classes and using inheritance, we can make our code more modular and extensible.

Sign up today for our weekly newsletter about AI, SEO, and Entrepreneurship

Leave a Reply

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


Read Next




© 2024 Menyu LLC