What is the Open-Closed Principle?
The Open-Closed Principle is one of the SOLID principles that is used to help developers write more maintainable and extendable software. It was first introduced by Robert C. Martin in his article and he describes it as:
“software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”
The idea was that once completed, the implementation of a class could only be modified to correct errors. New or changed features would require that a different class be created. That class could reuse coding from the original class through inheritance. The derived subclass might or might not have the same interface as the original class.
To break it down:
- Open for extension: This means that the behaviour of the module can be extended. And that we can make the module behave in new and different ways if the requirements of the application are to change, or to meet the needs of new applications.
- Closed for modification. The source code of a program should not change when the program changes its behaviours. No one should be allowed to make the source code changes.
Why should we use the Open-Closed Principle?
One benefit of using the Open-Closed Principle is that we do not have to reinvent the wheel if they can extend upon behaviours that have already been defined, hence this makes development much faster. Furthermore, if a feature implemented is no longer needed, then the changes can be easily reverted.
By making it closed for modification, we can reduce the chances of unwanted consequences such as bugs and errors. Furthermore, adding on to an existing code base increases additional complexity and this might break the existing system.
Example
class Shape {
public double calculateArea(Shape[] shapes) {
double area = 0;
for(Shape shape:shapes) {
if(shape instanceof Rectangle) {
//Calculate Area of Rectange
}
else if(shape instanceof Circle) {
//Calculate Area of Circle
}
}
return area;
}
}
class Rectangle extends Shape {
}
class Circle extends Shape {
}
In the above example, if we want to add or remove a new shape or even change the way area is calculated for one of the shapes, we would have to modify the calculateArea() method. Hence, this shows a poor design where Open-Closed Principle is not used.
abstract class Shape {
abstract double area();
}
class Rectangle extends Shape {
@Override
double area() {
// Area implementation for Rectangle
return 0;
}
}
class Circle extends Shape {
@Override
double area() {
// Area implementation for Rectangle
return 0;
}
}
Using the Open-Closed Principle, we can allow each of the shapes, to define their own area() method. We also have to create an abstract class called Shape, and have each of the different shapes extend it. Each shape can then overrides Shape’s abstract area() method, to compute its specific area. Hence, Shape is open for extension but closed for modification.
Conclusion
In conclusion, by using Open-Closed Principle, we can develop simpler and extensible components which are ready for change without breaking existing implementations.