Eduardo Julião

Posted on

# 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;
}
}
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, `Rectangle`and `Circle`can 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()
{
}
}
``````

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.