Under this statement hides simple definition – open for development / closed for modification. I would describe that principle as one of the hardest, because it requires from programmer an ability to forsee what are the chances of any problems that may occur driven in the future. It means, that every single class should be precisely thought before to provide new functionalities, without any modifications – they are forbidden, because of one crucial thing – any change of declaration may occur as a crash program result. Lets focus on code written below:
public class Square
{
public int A { get; set; }
}
public class Rectangle
{
public int A { get; set; }
public int B { get; set; }
}
public class Calculator
{
public int Area(object shape)
{
if (shape is Square square)
{
return square.A * square.A;
}
else if (shape is Rectangle rectangle)
{
return rectangle.A * rectangle.B;
}
return 0;
}
}
Ok – our code looks great – we have three different classes, and each class has its own responsibility. But there is a catch. What if we wanted to add another class figure called Circle? We would have to break the principle, and modify our Calculator class for another else if statement, which obviously would result as more lines of code. Thanks to benefits which we owe to OOP, there is a possibility to use polymorphism – a possibility for objects of various classes to be treated as objects of the common base class.
// created abstract class
public abstract class Shape
{
public abstract int Area();
}
// class Square inherits from Shape class
public class Square : Shape
{
public int A { get; set; }
public override int Area()
{
return A * A;
}
}
// class Rectangle inherits from Shape class
public class Rectangle : Shape
{
public int A { get; set; }
public int B { get; set; }
public override int Area()
{
return A * B;
}
}
//Calculator class provides a possibility to calculate any figure's Area
public class Calculator
{
public int Area(Shape shape)
{
return shape.Area();
}
}
This principle is very common to see while using design patterns, especially factory or strategy, which I’m discussing here. Thanks to this mechanism, there is a very simple way in the future to develop our code. I would like to point out, that we have applied a little bit another mechanism, fulfills dependency inversion principle, described here.