TF30 The Open Closed Principle 080823 123151
TF30 The Open Closed Principle 080823 123151
Imagine you have a large and complex codebase that is used by many other parts of the system. If you modify the code, you may introduce
bugs or break other parts of the system that depend on it. This is where the OCP comes in. By designing your code to be open for
extension but closed for modification, you can add new functionality without modifying existing code, thus minimizing the risk of introducing
bugs or breaking other parts of the system.
1. Enhances maintainability: When a class is open for extension but closed for modification, changes can be made to the behavior of the
class without modifying its existing code. This makes the code easier to maintain because changes can be made without introducing
new bugs or affecting existing behavior.
2. Improves modularity: By following the OCP, developers are encouraged to create modules that can be extended without modifying
their existing code. This makes it easier to compose larger systems from smaller, modular components, and makes the system more
flexible and adaptable to changing requirements.
3. Facilitates testing: Classes that follow the OCP are easier to test because they have well-defined interfaces that can be mocked or
stubbed during testing. This makes it easier to isolate the behavior of the class and test it in isolation.
4. Enhances code reuse: By creating modules that are open for extension, developers can create code that can be reused in different
contexts without requiring modification. This makes it easier to create libraries and frameworks that can be used by other developers to
build new applications.
5. Encourages better design: By following the OCP, developers are encouraged to create modular, flexible, and extensible code. This
leads to better overall software architecture and can make the code easier to understand, maintain, and extend over time.
Contnuing the previous example the bank decided to add Current Accounts functionality. Current account is similar to Savings account but
the deposit limits, withdrawal limits and interest rate calculations are different.
Next, we have to change TransactionService to have one more method to handle CurrentAccount transactions. You will also need to
implement corresponding methods in TransactionValidator , TransactionProcessor and TransactionConfirmationSender as well.
Now, if we look closely if we have to add one more account we again have to make a lot of changes in classes where we should not have
to. Here we are breaking open close principle.
So if we do not want to break open close principle one approach we can take is to extract an interface Account from SavingAccount and
CurrentAccount with two methods deposit and withdraw .
Now if the bank decided to add Salary Accounts functionality we can just create a class SalaryAccount that implements Account and
implement deposit and withdraw methods. There will be no changes in TransactionService, TransactionValidator ,
TransactionProcessor and TransactionConfirmationSender .
To summarize, the OCP suggests that classes should be open for extension but closed for modification. In the example above, we achieved
this by creating an interface that defines the behavior of all accounts, and then creating concrete classes that implement that interface. We
can add new accounts in the future by creating new classes that implement the Account interface, without modifying the existing code.
Code Smells
There are several typical "code smells" or signs that a class is not following the Open-Closed Principle (OCP). Here are a few examples:
1. Large conditional statements: If you find yourself writing large conditional statements that check for different cases or behaviors, it
may be a sign that your class is not open for extension. For example, if you have a switch statement that checks the type of an object
and then performs different actions based on that type, it may be difficult to extend the behavior of the class without modifying the
existing code.
2. Overuse of inheritance: If you are using inheritance to implement new behavior, it may be a sign that your class is not closed for
modification. For example, if you create a subclass of a class just to add new behavior, this may violate the OCP. Instead, you should
aim to use composition or interfaces to add new behavior.
3. Tight coupling: If your class is tightly coupled to other classes or modules, it may be difficult to extend its behavior without modifying the
existing code. For example, if your class relies on specific implementations of other classes, it may be difficult to swap out those
implementations without modifying the code.
4. Overuse of static methods or variables: If you are using static methods or variables to implement behavior, it may be a sign that your
class is not open for extension. Static methods and variables are difficult to override or extend, and can make it hard to change the
behavior of a class without modifying the existing code.
5. Lack of abstraction: If your class is too concrete and does not provide a way to abstract away its behavior, it may be difficult to extend
its behavior without modifying the existing code. For example, if you have a class that performs a specific operation, but does not provide
any way to customize that operation, it may be difficult to extend the behavior of the class.
These are just a few examples of code smells that may indicate a class is not following the Open-Closed Principle. By identifying and
addressing these smells, you can improve the modularity, maintainability, and extensibility of your code.