The Open Closed Principle (OCP) states that software entities (classes, modules, functions, etc.) should be open for extension and closed for modification.
Play explanatory video
In simpler terms, we should be able to add functionality to a software entity without modifying its existing source code.
# Extension and Modification?
- Extension: Adding new functionalities or behaviors.
- Modification: Changing existing code.
Software entities should be designed to allow adding new functionalities by extending their behaviors without modifying the existing code. This reduces the risk of introducing errors into already tested code and facilitates the maintainability and scalability of the system.
# Why is it important?
Maintainability
It is easier to maintain and add new features without risking affecting existing ones.
Robustness
Lower probability of introducing errors when modifying old code.
Reusability
Promotes code reuse, facilitating the creation of new functionalities.
# Symptoms of violation
We can identify when we are not respecting the Open Closed Principle:
- Constant need to modify existing classes when adding new functionalities.
- Difficulty in adding functionalities without breaking existing behavior.
- Rigid code that requires extensive changes for any update.
Example
Imagine an application for tax calculation across different regions.
Without Open Closed Principle
public class TaxCalculator { public double calculateTax(Product product, String region) { switch (region) { case "Region1": // Tax calculation for Region 1 break; case "Region2": // Tax calculation for Region 2 break; // ... more regions } return 0.0; } }
// Here, every time we add a new region or change the tax rules of an existing one, we have to modify the TaxCalculator class.
With Open Closed Principle
We create a TaxCalculator
interface:
public interface TaxCalculator { double calculateTax(Product product); }
And separate classes for each region:
public class Region1TaxCalculator implements TaxCalculator { public double calculateTax(Product product) { // Specific tax calculation for Region 1 return 0.0; } } public class Region2TaxCalculator implements TaxCalculator { public double calculateTax(Product product) { // Specific tax calculation for Region 2 return 0.0; } }
Conclusions
By implementing the Open Closed Principle, each RegionTaxCalculator can
be
changed or extended independently, without affecting others. This facilitates the addition
of
new regions and changes in the specific tax rules of a region without touching the existing
code.
Summary
OCP drives a software design where changes are an addition rather than a modification. Applying the OCP principle makes the code more robust, easier to maintain, and safer against changes, which in turn makes it less prone to errors and compatibility issues.