đĨ02A-Open-Closed Principle (OCP)
The Open-Closed Principle (OCP) is one of the five SOLID principles of object-oriented design. It states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. This means that you should be able to add new functionality to existing code without altering its source code.
Key Concepts
-
Closed for Modification:
- Existing code should not be changed when adding new features. This helps avoid introducing bugs and maintains the stability of the system.
- New features getting added to the software component should not have to modify the existing code.
-
Open for Extension:
- New functionalities can be added through new code, allowing the system to grow without modifying existing components.
Real-World Analogy
A practical analogy to understand OCP is the Nintendo Wii [Joy Stick] tool gaming console:
- The Wii console comes with a basic controller and allows for various accessories (like the Wii Zapper and steering wheel) to be added without modifying the console itself.
- This design ensures that users can enhance their gaming experience without needing to alter the core system.
Benefits of OCP
- Maintainability: Reduces the risk of bugs by keeping existing code untouched.
- Scalability: Facilitates easy addition of new features as requirements evolve.
- Reusability: Encourages the reuse of existing modules and classes in different contexts.
Implementation Example in Java
To illustrate OCP in practice, consider a scenario where you need to compare areas of different shapes:
Without OCP
class Square {
int height;
int area() { return height * height; }
}
class OpenOpenExample {
public int compareArea(Square a, Square b) {
return a.area() - b.area();
}
}
This approach requires modification if a new shape (like Circle) is introduced.
With OCP
By using an interface:
interface Shape {
int area();
}
class Circle implements Shape {
int radius;
int area() { return (int)(Math.PI * radius * radius); }
}
class Square implements Shape {
int height;
int area() { return height * height; }
}
class OpenClosedExample {
public int compareArea(Shape a, Shape b) {
return a.area() - b.area();
}
}
In this design, you can add new shapes without modifying existing code, adhering to the Open-Closed Principle.
Conclusion
The Open-Closed Principle encourages developers to design systems that are robust and adaptable.
By focusing on extending functionality rather than modifying existing code, developers can create more maintainable and scalable applications.
In future sessions, we will explore practical coding examples that demonstrate OCP in action.
đĨ02B-āĻāĻĒā§āύ-āĻā§āϞā§āĻāĻĄ āĻĒā§āϰāĻŋāύā§āϏāĻŋāĻĒāϞ: āĻā§āĻĄ āĻāĻĻāĻžāĻšāϰāĻŖ
āĻĒāϰāĻŋāĻāĻŋāϤāĻŋ
āĻāĻŽāϰāĻž āĻāĻāĻāĻŋ āĻā§āĻĄ āĻāĻĻāĻžāĻšāϰāĻŖ āĻĻā§āĻāĻŦ āϝāĻž āĻāĻ āύā§āϤāĻŋāϰ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύāĻā§ āĻāĻŋāϤā§āϰāĻŋāϤ āĻāϰāĻŦā§āĨ¤
āĻĒā§āϰā§āĻā§āώāĻžāĻĒāĻ
āϧāϰāĻŋ, One State āĻāĻāĻāĻŋ āĻŦā§āĻŽāĻž āĻā§āĻŽā§āĻĒāĻžāύāĻŋ āϝāĻž āĻŽā§āϞāϤ āϏā§āĻŦāĻžāϏā§āĻĨā§āϝ āĻŦā§āĻŽāĻžāϰ āϏāĻžāĻĨā§ āĻāĻĄāĻŧāĻŋāϤāĨ¤ āϤāĻžāĻĻā§āϰ āĻŦā§āĻŽāĻž āĻāĻŖāύāĻž āĻāĻāĻāĻŋ Java āϞāĻžāĻāĻŦā§āϰā§āϰāĻŋāϤ⧠āĻā§āĻĄ āĻāϰāĻž āĻšāϝāĻŧā§āĻā§āĨ¤
āĻā§āĻĄ āϏā§āύāĻŋāĻĒā§āĻ
āĻāĻāĻžāύ⧠āĻāĻāĻāĻŋ āĻā§āĻĄ āϏā§āύāĻŋāĻĒā§āĻ āϰāϝāĻŧā§āĻā§ āϝāĻž āĻĒā§āϰāĻŋāĻŽāĻŋāϝāĻŧāĻžāĻŽ āĻĄāĻŋāϏāĻāĻžāĻāύā§āĻ āĻā§āϝāĻžāϞāĻā§āϞā§āĻļāύ āĻĻā§āĻāĻžāϝāĻŧ:
class InsurancePremiumDiscountCalculator {
public double calculatePremiumDiscountPercent(HealthInsuranceCustomerProfile profile) {
if (profile.isLoyalCustomer()) {
return 10.0; // Loyal customer discount
}
return 0.0; // No discount
}
}
-
HealthInsuranceCustomerProfile āĻā§āϞāĻžāϏ⧠āĻāĻāĻāĻŋ
isLoyalCustomer()
āĻĒāĻĻā§āϧāϤāĻŋ āϰāϝāĻŧā§āĻā§ āϝāĻž āϏāϤā§āϝ (true) āĻĢā§āϰāϤ āĻĻā§āϝāĻŧ āϝāĻĻāĻŋ āĻā§āϰāĻžāĻšāĻ āĻāĻāĻāύ āĻŦāĻŋāĻļā§āĻŦāϏā§āϤ āĻā§āϰāĻžāĻšāĻ āĻšāϝāĻŧ, āĻ āύā§āϝāĻĨāĻžāϝāĻŧ āĻŽāĻŋāĻĨā§āϝāĻž (false) āĻĢā§āϰāϤ āĻĻā§āϝāĻŧāĨ¤
āύāϤā§āύ āĻā§āϝāĻžāϞā§āĻā§āĻ
āϧāϰāĻŋ, One State āĻā§āĻŽā§āĻĒāĻžāύāĻŋ āĻāĻāĻāĻŋ āύāϤā§āύ āĻāĻžāĻĄāĻŧāĻŋ āĻŦā§āĻŽāĻž āĻā§āĻŽā§āĻĒāĻžāύāĻŋ āĻ āϧāĻŋāĻā§āϰāĻšāĻŖ āĻāϰ⧠āĻāĻŦāĻ āϤāĻžāĻĻā§āϰ āĻā§āϝāĻžāĻāϞāĻžāĻāύ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰā§: "āĻāĻĒāύāĻžāϰ āϏā§āĻŦāĻžāϏā§āĻĨā§āϝ āĻāĻŦāĻ āĻāĻžāĻĄāĻŧāĻŋ āĻŦā§āĻŽāĻžāϰ āĻāύā§āϝ āϏāĻŦāĻāĻŋāĻā§"āĨ¤ āĻāĻāύ āĻāĻŽāĻžāĻĻā§āϰ āĻāĻžāĻĄāĻŧāĻŋ āĻŦā§āĻŽāĻžāϰ āĻĄāĻŋāϏāĻāĻžāĻāύā§āĻāĻ āϏāĻŽāϰā§āĻĨāύ āĻāϰāϤ⧠āĻšāĻŦā§āĨ¤
āύāϤā§āύ āĻā§āϞāĻžāϏ āϝā§āĻ āĻāϰāĻž
āĻāĻŽāϰāĻž āĻāĻāĻāĻŋ āύāϤā§āύ āĻā§āϞāĻžāϏ āϝā§āĻā§āϤ āĻāϰāĻŋ: VehicleInsuranceCustomerProfileāĨ¤ āĻāĻāĻŋ HealthInsuranceCustomerProfile āĻāϰ āĻŽāϤ⧠āĻāĻŦāĻ āĻāϰ isLoyal()
āĻĒāĻĻā§āϧāϤāĻŋ āϰāϝāĻŧā§āĻā§āĨ¤
class VehicleInsuranceCustomerProfile {
public boolean isLoyal() {
// Logic to determine loyalty
}
}
āϏāĻŽāϏā§āϝāĻž
āĻāĻāύ āĻāĻŽāĻžāĻĻā§āϰ InsurancePremiumDiscountCalculator āĻā§āϞāĻžāϏāĻāĻŋ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāϤ⧠āĻšāĻŦā§, āĻāĻžāϰāĻŖ āĻāϰ calculate
āĻĒāĻĻā§āϧāϤāĻŋ āĻŦāϰā§āϤāĻŽāĻžāύ⧠āĻļā§āϧā§āĻŽāĻžāϤā§āϰ HealthInsuranceCustomerProfile āĻ
āĻŦāĻā§āĻā§āĻ āĻā§āϰāĻšāĻŖ āĻāϰā§āĨ¤
OCP āϞāĻā§āĻāύ
- āύāϤā§āύ āĻŦā§āĻļāĻŋāώā§āĻā§āϝ āϝā§āĻ āĻāϰāĻžāϰ āĻāύā§āϝ āĻāĻŽāĻžāĻĻā§āϰ āĻŦāĻŋāĻĻā§āϝāĻŽāĻžāύ āĻā§āĻĄā§ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāϤ⧠āĻšāĻā§āĻā§, āϝāĻž āĻāĻĒā§āύ-āĻā§āϞā§āĻāĻĄ āĻĒā§āϰāĻŋāύā§āϏāĻŋāĻĒāϞā§āϰ āĻŦāĻŋāϰā§āĻĻā§āϧ⧠āϝāĻžā§āĨ¤
- āϝāĻĻāĻŋ āĻāĻŽāϰāĻž āĻŦāĻžāĻĄāĻŧāĻŋāϰ āĻŦā§āĻŽāĻžāĻ āϏāĻŽāϰā§āĻĨāύ āĻāϰāϤ⧠āĻāĻžāĻ, āϤāĻžāĻšāϞ⧠āĻāĻŦāĻžāϰ āĻā§āĻĄ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāϤ⧠āĻšāĻŦā§āĨ¤
āĻĄāĻŋāĻāĻžāĻāύ āĻĒā§āύāϰā§āĻāĻ āύ
āĻāĻŽāϰāĻž āĻāĻŽāĻžāĻĻā§āϰ āĻĄāĻŋāĻāĻžāĻāύāĻāĻŋ āĻĒā§āύāϰā§āĻāĻ āύ āĻāϰāĻŋ:
- CustomerProfile āύāĻžāĻŽā§ āĻāĻāĻāĻŋ āύāϤā§āύ āĻāύā§āĻāĻžāϰāĻĢā§āϏ āϤā§āϰāĻŋ āĻāϰāĻŋāĨ¤
- āĻāĻ āĻāύā§āĻāĻžāϰāĻĢā§āϏ⧠āĻāĻāĻāĻŋ āĻŽāĻžāϤā§āϰ āĻĒāĻĻā§āϧāϤāĻŋ āĻĨāĻžāĻāĻŦā§:
isLoyalCustomer()
āĨ¤ - āĻāĻāϝāĻŧ HealthInsuranceCustomerProfile āĻāĻŦāĻ VehicleInsuranceCustomerProfile āĻā§āϞāĻžāϏ āĻāĻ āϏāĻžāϧāĻžāϰāĻŖ āĻāύā§āĻāĻžāϰāĻĢā§āϏāĻāĻŋ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāϰāĻŦā§āĨ¤
interface CustomerProfile {
boolean isLoyalCustomer();
}
class HealthInsuranceCustomerProfile implements CustomerProfile {
public boolean isLoyalCustomer() {
// Logic for health insurance loyalty
}
}
class VehicleInsuranceCustomerProfile implements CustomerProfile {
public boolean isLoyalCustomer() {
// Logic for vehicle insurance loyalty
}
}
āύāϤā§āύ āĻā§āϝāĻžāϞāĻā§āϞā§āĻāϰ āĻā§āϞāĻžāϏ
āĻāĻāύ InsurancePremiumDiscountCalculator āĻā§āϞāĻžāϏā§āϰ āĻĒāĻĻā§āϧāϤāĻŋ āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāĻŋ:
class InsurancePremiumDiscountCalculator {
public double calculatePremiumDiscountPercent(CustomerProfile profile) {
if (profile.isLoyalCustomer()) {
return 10.0; // Loyal customer discount
}
return 0.0; // No discount
}
}
āϏā§āĻŦāĻŋāϧāĻž
- āĻāĻāύ āĻāĻŽāϰāĻž āϝāĻĻāĻŋ āĻŦāĻžāĻĄāĻŧāĻŋāϰ āĻŦā§āĻŽāĻžāϰ āĻāύā§āϝ āĻāĻāĻāĻŋ āύāϤā§āύ āĻā§āϞāĻžāϏ āϤā§āϰāĻŋ āĻāϰāĻŋ, āϝā§āĻŽāύ HomeInsuranceCustomerProfile, āĻāĻāĻŋ āĻļā§āϧā§āĻŽāĻžāϤā§āϰ CustomerProfile āĻāύā§āĻāĻžāϰāĻĢā§āϏāĻāĻŋ āĻŦāĻžāϏā§āϤāĻŦāĻžāϝāĻŧāύ āĻāϰāĻŦā§āĨ¤
- āĻāĻŽāĻžāĻĻā§āϰ InsurancePremiumDiscountCalculator āĻā§āϞāĻžāϏ⧠āĻā§āύ⧠āĻĒāϰāĻŋāĻŦāϰā§āϤāύ āĻāϰāϤ⧠āĻšāĻŦā§ āύāĻžāĨ¤
āĻāĻĒāϏāĻāĻšāĻžāϰ
āĻāĻŽāϰāĻž āĻĻā§āĻā§āĻāĻŋ āĻāĻŋāĻāĻžāĻŦā§ āĻĄāĻŋāĻāĻžāĻāύ āĻĒā§āύāϰā§āĻāĻ āύ āĻāϰ⧠āĻāĻĒā§āύ-āĻā§āϞā§āĻāĻĄ āĻĒā§āϰāĻŋāύā§āϏāĻŋāĻĒāϞ āĻ āύā§āϝāĻžāϝāĻŧā§ āĻāĻžāĻ āĻāϰāĻž āϝāĻžāϝāĻŧāĨ¤ āĻĒā§āϰāĻĨāĻŽā§ āĻĄāĻŋāĻāĻžāĻāύāĻāĻŋ OCP āĻ āύā§āϏāϰāĻŖ āĻāϰāĻāĻŋāϞ āύāĻž, āĻāĻŋāύā§āϤ⧠āĻĒā§āύāϰā§āĻāĻ āύā§āϰ āĻŽāĻžāϧā§āϝāĻŽā§ āĻāĻāĻŋ OCP-āϰ āϏāĻžāĻĨā§ āϏāĻžāĻŽāĻā§āĻāϏā§āϝāĻĒā§āϰā§āĻŖ āĻšāϝāĻŧā§ āĻāĻ ā§āĻā§āĨ¤
āĻāĻāύ āĻĄāĻŋāĻāĻžāĻāύāĻāĻŋ āĻāĻŦāĻŋāώā§āϝāϤā§āϰ āĻāĻā§āϏāĻā§āύāĻļāύā§āϰ āĻāύā§āϝ āĻāϰāĻ āĻļāĻā§āϤāĻŋāĻļāĻžāϞ⧠āĻāĻŦāĻ āĻāĻžāϰā§āϝāĻāϰā§āĨ¤
āĻāĻāĻŋ āĻāĻŋāϞ āĻāĻĒā§āύ-āĻā§āϞā§āĻāĻĄ āĻĒā§āϰāĻŋāύā§āϏāĻŋāĻĒāϞā§āϰ āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāϰāĻŖāĨ¤
đĨ02C-Key Takeaways from the Open-Closed Principle Code Example
Introduction
We will summarize the key takeaways from the previous code example that illustrated the Open-Closed Principle (OCP).
Principal Benefits of the New Design
-
Ease of Adding New Features
- The primary benefit of adhering to the Open-Closed Principle is the ease with which new features can be added to the system.
- This ease translates into cost savings for development and testing.
Cost Savings Explained
- If we do not follow OCP, adding new features often requires modifying existing code.
- Each modification increases the time spent on testing and quality assurance to ensure that no new bugs are introduced into the existing codebase.
- In contrast, when following OCP, testing new code is simpler and less time-consuming than running a full regression test suite on existing code.
- This principle is well-known among QA testers, who emphasize its importance in maintaining software quality.
Additional Benefits
-
Decoupling of Components
- By redesigning our system to conform to OCP, we inadvertently achieved a higher degree of loose coupling between components.
- This decoupling aligns with the Single Responsibility Principle (SRP), as each component now has a clearer purpose and responsibility.
Interconnectedness of SOLID Principles
- It is crucial to understand that the SOLID principles are intertwined and interdependent.
- They are most effective when applied together, providing a holistic approach to software design.
Cautionary Note
-
Do Not Follow OCP Blindly:
- While OCP is beneficial, blindly applying it can lead to an excessive number of classes, complicating your overall design.
- For instance, if you need to fix a bug and believe that modifying existing code is necessary for an effective fix, do so without hesitation.
- Avoid overhauling your design solely for bug fixes unless you notice recurring issues that could be mitigated by a redesign.
Subjective Application of OCP
- Deciding when and where to apply the Open-Closed Principle is subjective rather than objective.
- Use your judgment based on the specific context of your project.
Conclusion
- Re-designed code to make it follow OCP
- Following OCP can lead to cost benifits in the long run.
- OPC and SRP can work together to achieve a better design.
- Do not apply the OCPblindly and introduce unwanted complexity to your code.
The lessons learned from our code example related to the Open-Closed Principle. Understanding these key takeaways will help you apply OCP effectively in your future designs.
Top comments (0)