Principles

Last Updated: 3/15/2024

Open Closed Principle

  • Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
  • Extension means adding new features to the system without modifying that system. The plugin systems are the main example of OCP where new features are added using new features without modifying the existing ones.
  • In C#, Open/Closed principle can be applied using the following approaches:
    • Using Function Parameters
    • Using Extension methods
    • Using Classes, Abstract class, or Interface-based Inheritance
    • Generics
    • Composition and Dependency Injection

Example 1

Problem

public class Logger
{
    public void Log(string message)
    {
        Console.WriteLine(message);
    }

    public void Info(string message)
    {
        Console.WriteLine($"Info: {message}");
    }

    public void Debug(string message)
    {
        Console.WriteLine($"Debug: {message}");
    }
}
  • Some developers want to change debug messages to suit their needs. To satisfy their need, you need to edit the code of the Logger class and either create a new method for them or modify the existing Debug method.
  • If you change the existing Debug method then the other developers who don't want this change will also be affected.

Solution

public class Logger
{
    public virtual void Log(string message)
    {
        Console.WriteLine(message);
    }

    public virtual void Info(string message)
    {
        Console.WriteLine($"Info: {message}");
    }

    public virtual void Debug(string message)
    {
        Console.WriteLine($"Debug: {message}");
    }
}

public class NewLogger : Logger
{
    public override void Debug(string message)
    {
        Console.WriteLine($"Dev Debug -> {message}");
    }
}

Example 2

Problem

public class Course
{
    public string Type { get; set; }

    public void Subscribe(Student std)
    {
        Logger.Log("Starting Subscribe()");

        //apply business rules based on the course type live, online, offline, if any 
        if (this.Type == "online")
        {
            //subscribe to online course 
        }
        else if (this.Type == "offline")
        {
            //subscribe to offline course 
        }
    }
}
  • Whenever there is a requirement of adding a new type of course. We will have to add one more if condition or switch cases to process the course type.

Solution

public abstract class Course
{
    public int CourseId { get; set; }
    public string Title { get; set; }

    public abstract void Subscribe(Student std);
}
 
public class OnlineCourse : Course
{
    public override void Subscribe(Student std)
    {
        //write code to subscribe to an online course
    }
}

public class OfflineCourse : Course
{
    public override void Subscribe(Student std)
    {
        //write code to subscribe to a offline course
    }
}

Advantages of OCP:

  • Minimize the possibilities of error by not modifying existing classes.
  • Easily add new functionalities by adding new classes wherein no current functionality depends on the new classes.
  • Unit test each class