blog
Ottorino Bruni  

Open Closed Principle (OCP) in C#

In my previous articles I wrote about Solid Principles in C# and the Single Responsibility Principle.

In this article, I am going to show you when and how to use the Open Closed Principle in C# with an example project. You can find the repository on GitHub.

The master branch shows the initial code used in the example.  There are separate tags and branches for each of the all solid principles that you can review or download as well. Here are links you can use to jump to these tagged versions in your browser:

What is the Open Closed Principle (OCP) in C#?

The Open Closed Principle is one of the SOLID design principles. We can always reuse the definition from Wikipedia.

The Open Closed Principle states software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

So these software entities should be:

  • Open For Extension This means that the behavior of the module can be extended, for example we could add fields or new elements in the functions with a fixed behavior,
  • Closed for Modification The source code of such a module is inviolate. No one is allowed to make source code changes to it.

Why should you use the Open Closed Principle (OCP)?

  • Application robust. Don’t break existing code, prefer implementing new features in new classes, follow the SRP, no need to change tested class and less bug.
  • Flexible. Working with interfaces, it’s easy to accommodate new requirements and this reduces the cost of a business change requirement.
  • Better testability. Easy to test and less error prone.

How can i use the Open Closed Principle (OCP)?

These are the typical approaches to Open Closed Principle (OCP):

How to apply the typical approaches to Open Closed Principle (OCP)?

  • Base Class Example
public class ErrorLog
{
    public void WriteLog()
    {
        Console.WriteLine("Error");
    }
}
  • Apply Parameter Based Extension.
public class ErrorLog 
{ 
    public void WriteLog(string error) 
    { 
        Console.WriteLine(error); 
    } 
}
  • Apply Inheritance Based Extension
public class ErrorLog 
{ 
    public virtual void WriteLog() 
    { 
        Console.WriteLine("Error"); 
    } 
}

public class WarningLog 
{ 
    public override void WriteLog() 
    { 
        Console.WriteLine("Warning"); 
    } 
}
  • Apply Composition/Injection Extension
public class ErrorLog 
{ 
    private readonly MessageService messageService;
    public ErrorLog(MessageService messageService)
    { 
        this.messageService = messageService; 
    } 

    public void WriteLog() 
    { 
        Console.WriteLine(messageService.getMessage()); 
    } 
}

How we can refactor the code applying the Open Closed Principle (SRP)?

In order to apply the Open Closed Principle (SRP) we need an abstract Reviewer class and extend it for any DeviceType.

public abstract class Reviewer 
{ 
    protected readonly DeviceService service; 
    protected readonly ConsoleLog log; 

    public Reviewer(DeviceService service, ConsoleLog log) 
    { 
        this.service = service; 
        this.log = log; 
    } 
    
    public abstract void Evaluate(Device device); 
}

Let’s create a Factory that will eliminate the need for the switch statement.

public class ReviewerFactory {
    public Reviewer Create(Device device, DeviceService service) 
    { 
        switch (device.Type) 
        { 
            case DeviceType.Mobile: 
                return new MobileDeviceReviewer(service, service.Log); 
            case DeviceType.Tablet:
            ...

Or use the reflection inside the Factory to eliminate the need for the switch statement.

Why should you NOT use the Open Closed Principle (OCP)?

You should find the right compromise before applying the Open Closed Principle (SRP) 100%. Creating abstraction each time we want to modify our code can increase the complexity of the system and code readability.

As you can imagine, Open Closed Principle (SRP) it’s very important in libraries and NuGet packages. The consumers cannot change package contents and the consumers should not be able to extend the package to suit their own needs.

Please have a look at how I have refactored my previous code here OCP-END

If you think your friends/network would find this useful, please share it with them. I’d really appreciate it.

Thanks for reading! 🌟

 

 

Leave A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.