DEV Community

loading...

Open-closed principle

Eduardo Julião
Software Developer | Geek since 1993 | @monsieurxuxu on twitter
・2 min read

Open-Closed Principle (or OCP for short) states:

Objects or entities should be open for extension but closed for modification.

The "Open for Extensions" means that we need to develop our code to add functionalities when new requirements are created, and "Closed for Modifications" means that we already developed our code, that went through testing and validations, this could should only be altered in case a bug has been found.

public class Rectangle
{
    public double Height { get; set; }
    public double Width { get; set; }
}
Enter fullscreen mode Exit fullscreen mode
public class AreaCalculator
{
    public double TotalArea(Rectangle[] rectangles)
    {
        double result = 0;
        foreach(Rectangle rectangle in rectangles
            result += rectangle.Height * rectangle.Width;

        return result;
    }
}
Enter fullscreen mode Exit fullscreen mode

But our application recieved a new requirement for calculating the area of a circle.

public class Circle
{
    public double Radius { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

For this to work, we also need to change the AreaCalculator class.

public class AreaCalculator
{
  public double TotalArea(object[] shapes)
  {
      double result = 0;

      foreach(object shape in shapes)
      {
          if(shape is Rectangle)
          {
              Rectangle rectangle = (Rectangle)obj;
              result += rectangle.Height * rectangle.Width;
          }
          if(shape is Circle)
          {
              Circle circle = (Circle)obj;
              result += circle.Radius * circle.Radius * Math.PI;
          }
      }
    return result;
  }
}
Enter fullscreen mode Exit fullscreen mode

With these modifications, we added a Circle to our application.
But what if we need to add a Triangle or a Square? We would need to add more and more if statements to our TotalArea method.
This is where the Open-Closed Principle comes into our aid.
In this example, Rectangleand Circlecan derive from the same abstract concept, a Shape.

public abstract class Shape
{
    public double CalculateArea();
}
Enter fullscreen mode Exit fullscreen mode

Now, let's use the Shape class in our "Shapes".

public class Rectangle: Shape
{
    public double Height { get; set; }
    public double Width { get; set; }

    public double CalculateArea()
    {
        return Height * Width;
    }
}

public class Circle: Shape
{
    public double Radius { get; set; }

    public double CalculateArea()
    {
        return Radius * Radius * Math.PI;
    }
}
Enter fullscreen mode Exit fullscreen mode

With our Shapes implementing the CalculateArea from our Shape class, we need to update the AreaCalculator class.

public class AreaCalculator
{
  public double TotalArea(Shape[] shapes)
  {
      double result = 0;

      foreach(Shape shape in shapes)
      {
          result += shape.CalculateArea();
      }

    return result;
  }
}
Enter fullscreen mode Exit fullscreen mode

With these changes, now we're implementing the Open-Closed principle. Our application is open for extensions (creating a Triangle class for example) but closed for modifications, only modifying if any bugs were founds.

Discussion (0)