Click here to Skip to main content
Click here to Skip to main content

Understand Open Closed Principle and Dependency Inversion

, 5 May 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
This article will help you better understand OCP and DI.

Introduction

Here I am going to discuss the Open closed and Dependency inversion principle of SOLID . Now what does SOLID means ? SOLID is object oriented design principle , Where each letter has it own meaning

  • S-> Single responsibility
  • O-> Open Closed
  • L-> Liskov substitution 
  • I-> Interface segregation 
  • D-> Dependency inversion

According to Wikipedia the definition of SOLID is   

" SOLID are guidelines that can be applied while working on software to remove code smells by causing the programmer to refactor the software's source code until it is both legible and extensible. "

Using the code  

Before start technical discussion i want to answer the below questions :

What is Open closed principle ?

Answer: " software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification " 

What is Dependency inversion ?

Answer:

  • High-level modules should not depend on low-level modules. Both should depend on abstraction. 
  •  Abstractions should not depend upon details. Details should depend upon abstractions. 

Let's consider an example to make it better understand. Suppose I need a computer, not decided yet whether I need laptop,desktop ,tablet or other. Suppose I went to a Computer Shop and ask for desktop computer.  Let's convert my requirements into code.

public class Desktop 
{
    public string GetComputerDescription()
    {
        return " You get a Desktop";
    }
}

public class Laptop
{   
    public string GetComputerDescription()
    {
        return " You get a Laptop";
    }
}

public class ComputerShop
{
    public enum ComputerType
    {
        Laptop, Desktop
    }
 
    public ComputerShop()
    {
    }
    public string GetMyComputerDescription(ComputerType cmptype)
    {
        var myComp = string.Empty;
        if (ComputerType.Desktop == cmptype)
        {
            myComp = new Desktop().GetComputerDescription();
        }
        else if (ComputerType.Laptop == cmptype)
        {
            myComp = new Laptop().GetComputerDescription();
        }       
        return myComp;
    }
}

So, I ask for a desktop computer  right

var computerShop = new ComputerShop();
computerShop.GetMyComputerDescription(ComputerShop.ComputerType.Desktop);

If you run the code it will execute fine and give you a output "You get a desktop ". So whats wrong ? Here we are violating the rule of OCP (Open Closed principle) and DI (Dependency inversion) 

  • Closed for modification ( we did violation of OCP)
  • High-level modules should not depend on low-level modules. Both should depend on abstraction. (we did violation of DI)

Still confuse ?  No problem i am explaining.

How we violate the modification rule ? 

Yes we did it by creating the object of DeskTop and Laptop Class on GetMyComputerDescrition method. Because if a new type comes then we need to modify the function as well as class enam .

How we violate DI Principle ?

Yes we did it by creating the low level object ( DeskTop  and Laptop ) on high level object (ComputerShop) . So High level modue (ComputerShop) depends on low level module (Laptop , desktop) and no abstraction here.

Now I am adding a new type (Tablet) and modify my class by violation the OCP . Look at the violated code below    

public class ComputerShop
{
    public enum ComputerType
    {
        Laptop, Desktop, Tablet  // Violation of OCP
    }
 
    public ComputerShop()
    {
    }
    public string GetMyComputerDescription(ComputerType cmptype)
    {
        var myComp = string.Empty;
        if (ComputerType.Desktop == cmptype)
        {
            myComp = new Desktop().GetComputer();
        }
        else if (ComputerType.Laptop == cmptype)
        {
            myComp = new Laptop().GetComputer();
        }                                         // Violation of OCP
        else if (ComputerType.Tablet == cmptype)
        {
            myComp = new Tablet().GetComputer();
        }
        return myComp;
    }
} 

Did you notice the violation ? Yes we modify the class as new type introduce, Now lets follow the OCP  & DI rule and implement a new structure . If we can get the required computer without crating the objects on shop class then we can achieve our goal . Now we are going to introduce the abstraction  . 

public interface IComputer
{
    string GetComputerDescrption();
}
 
public class Desktop : IComputer
{
   
    public string GetComputerDescrption()
    {
        return " You get a Desktop";
    }
}
public class Laptop:IComputer
{   
    public string GetComputerDescrption()
    {
        return " You get a Laptop";
    }
}
public class Tablet : IComputer
{
    public string GetComputerDescrption()
    {
        return " You get a new Tablet yahooooooooooooooooo";
    }
}

public class ComputerShop
{   
    public string GetMyComputerDescription(IComputer cmptype)
    {
        // No matter how many types of computer comes 
        var myComp = cmptype.GetComputerDescrption();
        return myComp;
    }
}

var computer = new ComputerShop();
computer.GetMyComputerDescription(new Tablet());

We introduce an Interface (IComputer) to remove the dependency from ComputerShop , Desktop and Laptop Class . Also now both high level and low level module depends on abstraction not on each other and
the abstraction is not depends on details so if the details change they should not affect the abstraction (satisfy DI ). Now  we extend our new item (Tablet) without modify the ComputerShop class (satisfy OCP ).

Points of Interest

So the interface gives an extendability and remove dependency. Now whatever computer type comes, Shop class does not need to depend on any lower level module.

public class AnotherNewItem: IComputer
{
    public string GetComputer()
    {
        return " You get a Another New Item Hurrayyyyyyy";
    }
}

It simply gives the product we need  from abstraction

public class Shop
{   
    public string GetMyComputer(IComputer cmptype)
    {
        // No matter how many types of computer comes 
        var myComp = cmptype.GetComputer();
        return myComp;
    }
}

So now our code satisfy the both DI and OCP.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Faisal(mfrony)

Bangladesh Bangladesh
I am a Sr.Software Engineer at Brain Station -23. I have 5+ years of work experience in .Net technology. I strongly believe that before software can be reusable it first has to be usable.
 
My contact info :
 
mfrony2003@yahoo.com
mfrony2003@hotmail.com
 
LinkedIn
http://www.linkedin.com/profile/view?id=106671466&trk=tab_pro

Comments and Discussions

 
GeneralMy vote of 5 PinmemberShahdat Hosain25-Dec-13 18:23 
QuestionAnother suggestion PinmemberGovindaraj Rangaraj22-Oct-13 0:02 
GeneralMy vote of 4 PinmemberMohammed Hameed6-May-13 23:43 
GeneralMy vote of 4 PinmemberOshtri Deka6-May-13 2:21 
QuestionThanks PinmemberMike DiRenzo3-May-13 12:40 
AnswerRe: Thanks PinmemberPCoffey6-May-13 5:13 
QuestionA few suggestions. PinmemberGeorge Swan2-May-13 21:29 
AnswerRe: A few suggestions. PinmemberFaisal(mfrony)2-May-13 23:38 
GeneralMy vote of 5 Pinmembermanoj kumar choubey2-May-13 19:24 
GeneralRe: My vote of 5 PinmemberFaisal(mfrony)2-May-13 19:47 
GeneralMy vote of 5 PinmemberMichael Buswell2-May-13 15:06 
GeneralRe: My vote of 5 PinmemberFaisal(mfrony)2-May-13 19:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141216.1 | Last Updated 6 May 2013
Article Copyright 2013 by Faisal(mfrony)
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid