The Open Closed Principle of SOLID

SOLID principles are like the backbone of OOP, I've gone through with this and obtained a good understanding of this and I thought to share it so that anyone can understand this principle at MAX.

Here is the list of SOLID principles.

SRP

The Single Responsibility Principle

A class should have one, and only one, reason to change.

OCP

The Open Closed Principle

You should be able to extend a classes behavior, without modifying it.

LSP

The Liskov Substitution Principle

Derived classes must be substitutable for their base classes.

ISP

The Interface Segregation Principle

Make fine grained interfaces that are client specific.

DIP

The Dependency Inversion Principle

Depend on abstractions, not on concretions.

Today I am hilighting the Open Closed Principle of SOLID.

Software entities should be open for extension, but closed for modification: Robert Martin

The preceding statement may be a bit confusiing to understand for those who are not very familiar with these principles.

Open for Extension: A class should be open for extension only (for example a derived class or subclasses).

Closed for modification: A class shouldn't be open of modification (for example we should not add code on demand whenever required).

One thing is sure in all software development, most software changes during its life cycle. So, it requires assurance that developers design software that is stable.

For example, let's say you are creating a class to represent an Export. The Export class will export the information/dataset to the desired format like a list of employees and related information to a CSV and text format on behalf of the specified provider. The following sample example is for illustrative purposes only:

    public enum ProviderName

    {

        SQlServer

     }

 

    class Export

    {

 

        public void ExportFileToDesiredFormat(Provider objProvider)

        {

            if (objProvider == ProviderName.SQlServer)

            {

                //Export to CSV,text,.pdf format code segment which depands     on provider

               return true;

            }

return true;

 

        }
    }

Now everything looks great. Suppose we come up with one more desired export format. Then at development time it will look like this that is connected with an OLEDB connection:

public enum ProviderName

{

    SQlServer,

    OLEDB,

    Oracle

}

 

class Export

{

    public bool ExportFileToDesiredFormat(string objProvider)

    {

        if (objProvider == ProviderName.SQlServer.ToString())

        {

            //Export to CSV,text,.pdf format code segment which depands on provider

            return true;

        }

        else if (objProvider == ProviderName.OLEDB.ToString())

        {

            //Export to CSV,text,.pdf format code segment which depands on provider

            return true;

        }

        else if (objProvider == ProviderName.Oracle.ToString())

        {

            //Export to CSV,text,.pdf format code segment which depands on provider

            return true;

        }

        else { }

          return true;

    }

}


Here if you can see from the code above, we are modifying the class Export rather than extending, in other words whenever we add a new export format then we are modifying the existing class that violates the OCP.

It's time to remember OCP: entities should be open for extension and closed for modification.

Here is the code segment after considering OCP in mind. The sample example is for illustrative purposes only.
 

interface IProvider

{

    bool connect(string objProviderName);

}

class ExportFileFromSQLProvider : IProvider

{

    public bool connect(string objProviderName)

    {

        //write code on behalf of provider to get connect with SQLProvider and export dataset to desired format such as .csv,.pdf,.text

        return true;

    }

}

class ExportFileFromOLEDBProvider : IProvider

{

    public bool connect(string objProviderName)

    {

        //write code on behalf of provide to get connect with OLEDBProvider and export dataset to desired format such as .csv,.pdf,.text

        return true;

    }

}

class ExportFileFromOracleProvider : IProvider

{

    public bool connect(string objProviderName)

    {

        //write code on behalf of provide to get connect with OracleProvider and export dataset to desired format such as .csv,.pdf,.text

        return true;

    }

}

The main method will look like:

class Program
{
    static void Main(string[] args)
    {
        IProvider objSQLIProvider = new ExportFileFromSQLProvider();
        bool sucess = objSQLIProvider.connect("sqlprovider");
        IProvider objOLEDBIProvider = new ExportFileFromOLEDBProvider();
        bool result = objOLEDBIProvider.connect("OLEDBProvider");
    }
}

Using this approach we can add as many ProviderNames to export a file as needed. Thus the IProvider interface implements the idea of open for extension but closed for modifications.

It's very easy to understand, especially for those who are not familiar with this principle. Hope you enjoyed this demonstration.

Enjoy Coding.


Similar Articles