Open-closed principle

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; }
}
public class AreaCalculator
{
    public double TotalArea(Rectangle[] rectangles)
    {
        double result = 0;
        foreach(Rectangle rectangle in rectangles
            result += rectangle.Height * rectangle.Width;

        return result;
    }
}

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

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

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;
  }
}

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();
}

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;
    }
}

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;
  }
}

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.

4