Sunday, December 11, 2016

DIP - Dependency Inversion Principle - Example

In previous post we covered what is DIP. Here I am going to show one more example of DIP.

Lets see a real- time example, we all know that whenever a bill is printed, an invoice is required to be generated and whenever an invoice is generated a bill must be printed. Lets assume that we have two classes Bill and Invoice as below.


When the below code is executed, we get the stack overflow error.

Now how do we solve this issue? This is where DIP comes into the picture, where we inject the dependencies to the dependent object. See the below code how the dependencies are injected to resolve stack overflow issues.



What we saw in above example is to achieve DIP using Constructor injection. 

PS: DIP is just the principle which requires that all your code's entities to depend only on the details they really need. DI is a process of passing the "abstract details" to the entity that really needs these derails. 

Saturday, December 10, 2016

DIP - Dependency Inversion Principle

DIP says - The high-level modules/classes should not depend upon low-level modules/classes. Both should depend upon abstractions. Secondly, abstractions should not depend upon details. Details should depend upon abstractions.

It means that if a class has dependencies on other classes, it should rely on dependencies' interface in place of their concrete types. Basically it helps in developing loosely coupled code.

DIP is some way related to Dependency Injection (DI) pattern but it doesn't imply Dependency Injection. DIP just says that higher layers of your application should not directly depend on lower layers. DIP doesn’t say anything about how higher layers know what lower layer to use. This could be done by using Dependency Injection or Service Locator patterns.

Let's understand DIP with an example: Think of an application which has 4 layers, Presentation Layer, Application Layer, Business Layer and Data Access Layer. The Presentation layer is the highest layer and directly depends on or communicates with the Application Layer. The Application layer is higher level than Business Layer and depends on or communicate with the Business Layer and so on. 

When DIP is applied this relationship between layers are reversed. The Presentation Layer defines the abstractions it needs to interact with the Application Layer.  The Application Layer defines the abstractions it needs to interact with the Business Layer. The Business Layer defines the abstractions it needs to interact with the Data Access Layer. Basically the higher layer defines the abstraction and lower layer implements those abstractions.

Presentation Layer ----> Services Layer -----> Business Components Layer ----> Data Access Layer
DIP may put abstraction in the layers defining them, for example Presentation Layer contains Presentation Layer logic and the Service Layer Abstractions (abstract classes and interfaces). The Services Layer contains Service Logic and Business Layer Abstractions (abstract classes and interfaces) and so on. In this case of DIP application the Data Access Layer depends upon the Business Layer, the Business Layer depends on the Service Layer and the Service Layer depends on the Presentation Layer. The dependencies (references) are inverted hence the name of the principle.


I don't follow the above approach in my projects what I do instead is define Presentation, Services, Business and Data Access Layers as different assemblies. I also make Interfaces as different assemblies like Service Interfaces, Business Interfaces, and Data Access Interfaces.   


Since the layers interacts with each other through interfaces, the second intent (abstractions should not depend  on details. Details should depend on abstractions) of the DIP is also full-filled.  The best part about this principle is, it makes the code unit testable, like in the above example each layer can be tested independently.

Lets see DIP with an example, lets assume that we have a high level class called Manager class which represent a person that manages the workers and a low level class called Worker which represents the person a Manger class manages.

public class Worker {
   public void Work()
   {
        // working...
   }
}

public class Manager {
   private IList<Worker> objWorkers;
   public Manager(List<Worker> workers)
  {
          objWorkers =  workers;
  }
   public void Manage()
  {
        foreach (var worker in objWorkers )
             worker.Work();
   }
}

Let's say now few specialised workers are being introduced. We created a new class SuperWorker for this.

public class SuperWorker {
   public void Work()
   {
        // working...
   }
}

Now will have to be modified Manager class to accommodate SuperWorker class, which is going to break OCP. So how should we resolve this issues? This is where the DIP comes into the picture. Now create and IWorker interface and make Manager use IWorker instead of Work class. 

public interface IWorker{
    public void Works();
}

public class Worker : IWorker {
   public void Work()
   {
        // working...
   }
}

public class SuperWorker : IWorker {
   public void Work()
   {
        // working...
   }
}

public class Manager {
   private IList<IWorkable > objWorkers;
   public Manager(List<IWorkable > workers)
  {
          objWorkers =  workers;
  }

   public void Manage()
  {
        foreach (var worker in objWorkers )
             worker.Work();
   }
}

Let's say now a Robot is being introduce the only thing we need to do is make Robot implement the IWorker interface & no additional changes in the existing classes.

public class Robot: IWorker {
   public void Work()
   {
        // working...
   }
}

ISP - Interface Segregation Principle

ISP says - Many client-specific interfaces are better than one general-purpose interface. 
(The clients should not be forced to implement interfaces they don't use. Instead of one fat interface many small interfaces are preferred based on groups of methods, each one serving one sub module.)

This means that create the interfaces such a way that it is closely related to the code that uses it than the code which is going to implement it (Basically it says that define interfaces based on the methods which clients need than which method class implements). So that clients are not forced to implement the interfaces which they do not use.

Basically ISP is nothing but Interface Re-engineering.  

Let's see ISP with an example, suppose we have an application to print Documents and PDFs, we can print the Documents and PDFs either in colour or no-colour.

interface IPrint{
     public void Print();
     public void SetColour();
}

class Document : IPrint{
  // interface or other implementation goes here
}

class PDF: IPrint {
  // interface or other implementation goes here
}

Lets say now a new requirement comes to add the TextDocument. As we already have IPrint interface we can ask TextDocument to implement the interface IPrint but then the TextDocument class doesn't need SetColour() method because text are never required to be printed in colour. How do we over come this issue? This is where the ISP comes into the picture.

First lets try to divide IPrint interface to two interface as below:
interface IPrint{
   public void Print();
}

interface IColour {
   public SetColour();
}

Then ask new class TextDocument to implement IPrint() and existing classes to implement IColour as well as IPrint. Well, this would be wrong as it violates OCP in existing Document and PDF classes (since we are modifying them to implement the new interface). We shouldn't be modifying the exiting classes, so how should we resolve this issues now?

Well, this can be done easily, by introducing a new interface IBasePrint and moving Print() method in it and making interface IPrint and class TextDocument to implements interface IBasePrint.

interface IBasePrint{
    public Print();
}

inteface IPrint : IBasePrint
{
     public SetColour();
}

class TextDocument: IBasePrint
{
  // interface or other implementation goes here
}

PS: Like Classes, each interface should have a specific purpose/responsibility (refer to SRP). Don't force the class to implement an interface when object doesn't share the purpose. The larger the interface, the more likely it includes methods that are not required by all implementer. 

LSP - Liskov's Substitution Principle

LSP is an extension to OCP and it says - Derived class (sub class) must be completed substituted for it's base class (parent class).

This means that we must ensure that new derived classes extend the base classes without changing their behaviour.

See the example explained in OCP where Rectangle, Circle, Square are being substituted for Shape class without changing it's behaviour.  


Example where LSP is violated: 
  • Lets say we have an application which uses Rectangle class as described below:
  • The application works well and installed in may sites. Lets say one day user demands to have Squares along with Rectangles in the application. In mathematics a Square is an specialisation of a Rectangle which makes an "IS A" relationship, and makes us model this with an Inheritance. So in our code we made Square inherit from Rectangle as below. 
  • The SetWidth() and SetHeight() methods are inappropriate for a Square as the width and height of the square are identical. This is the significant clue that there is a problem with the design. However, there is a way to subside this as shown in below code:
  • Lets say we have a method Test() as below and we pass reference to Square object in this method, the Square object will be corrupted because the height won't change. This is a clear violation of LSP, function Test() doesn't work with for derivatives of its' arguments. The reason for this is SetWidth() and SetHeight() are not declared as virtual in Rectangle class.
  • We can fix this easily as shown in below code. However, when the creation of a derived class causes us to make changes to the base class, it often implies that the design is faulty. Indeed, it violates the Open-Closed principle.  



  • So far it's good, lets say we have a method TestArea() as shown below. This method calls SetWidth() as well as SetHeight() members considering it is a Rectangle. The assertion works fine when an object of Rectangle class is passed but not for an object of Square class. Since, this methods takes reference of type Rectangle but cannot operate upon Square, which violates LSP. Making Square class derived from Rectangle class has broken method TestArea(), as we may have to put a conditional check to determine if the object passed is not the type of Square for assert to pass, which in-turn violated the OCP.
So what went wrong? in above example. Isn't a Square a Rectangle? Doesn't a "IS A" relationship hold between them?  No! A square might be a rectangle, but a Square object is not a Rectangle object. This is because the behaviour of a Square object is not consistence with the behaviour of a Rectangle object. It's the behaviour that software is really all about.

The LSP makes clear that in OOD the "IS A" relationship pertain to behaviour. Not intrinsic private behaviours, but extrinsic public behaviour; the behaviours clients depends upon. In order for the LSP to hold, and with it the Open-Closed principle, all derivatives must conform to the behaviour that clients expect of the base classes that they use.


There is a strong connection between the LSP and Design by Contract. Design by Contract says, that methods of a class has pre-conditions and post-conditions. The preconditions must be true in order for the method to execute. Upon completion, the method guarantees that the post-condition will be true. 

The rules for precondition and post-condition for derived class says that while redefining a method in derived class, you may only replace it's precondition by a weaker one, and its post condition by a stronger one.  In other words, when using an object through its base class interface, the user knows only the preconditions and post-conditions of the base class. Thus, derived objects must not expect such users to obey preconditions that are stronger then those required by the base class. That is, they must accept anything that the base class could accept. Also, derived classes must conform to all the post-conditions of the base. That is, their behaviours and outputs must not violate any of the constraints established for the base class. Users of the base class must not be confused by the output of the derived class.

OCP - Open Closed Principle - Example

Example of OCP - A fruit selling application which has SalesManager class as below:

The problem with the above SalesManager code is that, whenever a new fruit is being introduced, the method SellFruits() needs to be modified which breaks OCP. So now, how do we resolve this issue? We can do something like below code:


Now, if a new fruit is being introduced, we don't need to modify method SellFruits() of SalesManager class, we just have to create a new class and make that class implement IFruit interface.

The fruit checking logic need to be moved to some place, in this case it is being moved to the class who is making use of the class SalesManager. So whenever a new fruit is being introduced only this par of the code need to be modified.

Well, the above code can be fixed using reflection, if the Assembly name is known and the fruit name resembles the fruit class created. Even if there is a new fruit introduced, there is no change required in the code if the code is written as below using reflection. 



Basically while using the above code we will be having classes like below, and based on the fruitName variable value, the instance of that class will be created during run-time.
  • For apple - OCP.Apple.
  • For orange OCP.Orange
  • For pineapple - OCP.Pineapple
  • For banana - OCP.Banana

OCP - Open Closed Principle

OCP says -  A software module/class is open for extension and closed for modification.

"Open for extension" means we need to design our module/class in such a way that the functionalities can be added only when new requirements are generated. 
"Close for modification" means we need not alter the existing class (which have already developed and has gone through unit testing) until a bug comes.

Lets see OCP with an example, suppose we have a rectangle class with height and width and our application needs to calculate the total area of the collection of rectangles. By applying SRP, we cannot add total area calculation code inside Rectangle class, so I have created a new class call ed AreaCalculator. 

public class Rectangle {
     public double Width { get; set; }
     public double Height { get; set; }
}

public class AreaCalculator {
    double area;
    public double TotalArea(List<Rectangle> rectangles)
    {  
        foreach(var item in rectangles) {
            area+= (item.Width * item.Height);
        }
        return area;
     }
}

Lets say now we need to extend our application to support circle. Now we have an issue because the AreaCalculator just takes the list of type Rectangle, but we can change this method a bit to accommodate Circle as below:

public class Circle{
    public double Radius { get; set; }
}

public class AreaCalculator {
    double area;
    public double TotalArea(List<Object> shapes)
    {  
        foreach (var item in shapes) 
        {
           if (item is Rectangle)
           {
                var rectangle = (Rectangle) item;
                area+= (rectangle .Width * rectangle .Height);
           }
          if (item is Circle)
          {
                 var circle = (Circle) item;
                area+= (circle.Radious * cirlce.Radious * Math.PI);              
          } 
        }
        return area;
     }
}

Let's say now we need to extend our application to accommodate Tingle, Square and other shapes, we will have to add new if conditions in TotalArea method which makes class AreaCalculator as open for modification  (which violates OCP). To overcome this problem we can do the following:

public abstract class Shape {
     public abstract double Area();
}

public class Rectangle : Shape {
     public double Width { get; set; }
     public double Height { get; set; }
     public override double Area(){
           return (Width *  Height);
     }
}


public class Circle : Shape {

    public double Radius { get; set; }    
    public override double Area()
    {
           return (Radius *  Radius * Math.PI);
     }
}


public class Square : Shape {

    public double Side{ get; set; }
    public override double Area()
    {
           return (Side *  Side);
     }
}

public class AreaCalculator {

    double area;

    public double TotalArea(List<Shape> shapes)
    {  
        foreach (var item in shapes) 
        {
            area += item.Area();
        }
        return area;
     }
}

Whenever a new shape is introduced the new shape class has to derive from "Shape" abstract class and we don't need to modify AreaCalculator class. 

Now our code is following SRP as well as OCP.  Awesome! Isn't it?

Friday, December 9, 2016

SRP - Single Responsibility Principle

SRP says - Every software module should have only one reason to change.

This means that a class or similar structure should have only one job to do. It doesn't mean that a class should have only one method or property, it can have many members (methods and properties ) as long as they related to single responsibility.

Swiss knife is the real-life example where SRP is broken, that's because the tool requires alteration if any one of the item needs changes.   

Lets see SRP with the example below:
public class UserService {
      public void Register()
     {
          // validate email
          // Register User
         // send confirmation mail to user
     }

      public bool ValidateEmail()
     {
     } 


      public bool SendMail()
     {
     }

}

We have a UserService with Register method which registers the user after validating e-mail ID and then sends the e-mail confirmation to the user. In this implementation of UserService, it violets SRP, since it's not only does the user registration but also the email validation and sending confirmation e-mail to user. To overcome this issue create one more class and move ValidateEmail() and SendMail() method to it.

public class EmailService()
{
      public bool ValidateEmail()
     {
     } 


      public bool SendMail()
     {
     }

}

Now the UserService class looks as below:
public class UserService {

      public void Register()
     {
          // validate email using EmailService
          // Register User
         // send confirmation mail to user using EmailService.
     }
     
}
  
Advantages:
  • Gives a good way to identify classes at the design phase of an application and makes you think of all the way a class can change.
  • Reduces Code complexity.
  • Improves Readability.
  • Reduces Coupling.
  • Code gets better chance of cleanly evolving.
PS: SRP is not about code-reuse.