Category Archives: Design pattern

Repository + Unit Of Work Pattern Demystified

The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD).

Creating a repository class for each entity type could result in a lot of redundant code, and it could result in partial updates. For example, suppose you have to update two different entity types as part of the same transaction. If each uses a separate database context instance, one might succeed and the other might fail. One way to minimize redundant code is to use a generic repository, and one way to ensure that all repositories use the same database context (and thus coordinate all updates) is to use a unit of work class.

A repository is nothing but a class defined for an entity, with all the operations possible on that specific entity. For example, a repository for an entity Customer, will have basic CRUD operations and any other possible operations related to it. A Repository Pattern can be implemented in Following ways:

  • One repository per entity (non-generic) : This type of implementation involves the use of one repository class for each entity. For example, if you have two entities Order and Customer, each entity will have its own repository.
  • Generic repository : A generic repository is the one that can be used for all the entities, in other words it can be either used for Order or Customer or any other entity.

Unit of Work in the Repository Pattern

Unit of Work is referred to as a single transaction that involves multiple operations of insert/update/delete and so on kinds. To say it in simple words, it means that for a specific user action, all the transactions like insert/update/delete and so on are done in one single transaction, rather then doing multiple database transactions. This means, one unit of work here involves insert/update/delete operations, all in one single transaction.

Repository pattern minus the Unit of Work Pattern provides of lot challenges an anti patterns

  • Each repository requires one interface and one concrete class per “provider” (“entity framework” or “in memory”). If you are starting to have quite some repositories, then interfaces and implementation grows. If you have “custom” specialized methods for each repository, it also means implementing them for all the providers.
  • One abstract type per repository equals one parameter in your controller constructor per repository that needs to be accessed by the controller. If a controller is performing operations on multiple repositories, this can quickly become a mess with a lot of parameters in the constructor (even if constructor will never be called explicitly by your code but by the DI container -constructor injection- it still looks kind of crapy). Moreover if you need to add access to a new repository in a controller, it means adding a new parameter to the constructor and doing a new binding in your DI container.
  • By injecting repositories individually in each controller, the true power of the unit of work pattern is completely bypassed.
    Indeed, through this basic design, to illustrate via EF Code First, a DbContext (EF UnitOfWork) is usually instantiated per repository and “at best” a Commit method is present in each repository to call SaveChanges on the DbContext (and apply all modifications to DB) once all operations have been done on the repository. At worse the call to SaveChanges on the DbContext is done in each repository method performing modifications in the repository. You are using a nice loose coupled design, playing nicely with dependency injection and unit testing but you are shooting yourself a bullet in the head by not correctly using the UnitOfWork pattern.The main problem with this incorrect use of the unit of work pattern is that for a specific user request, triggering call to action method and potentially accessing multiple repositories, doing work on them, you are creating multiple unit of works whereas a single unit of work should be used !The definition of the Unit Of Work pattern is rather clear : “Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.” (http://martinfowler.com/eaaCatalog/unitOfWork.html).The business transaction here is typically triggered by the end user, indirectly calling an action method. It starts when the end-user triggers the operation, and ends when the operation is completed, whatever the number of repositories accessed and the number of CRUD operations performed on them. This means that a single unit of work should be used in the context of the operation/transaction (the request) and not many different ones.Typically, to use Entity Framework as a provider example, following this bad design would result in calling SaveChanges multiple times, meaning multiple round trips to DB through multiple transactions which is typically not the behavior wanted (and absolutely not the Unit Of Work philosophy).Apart from the performance aspect, it also leads to a problem when an error/exception happens in the middle of an operation in an action method. If you already made some changes in some repositories and commited the changes, but the global operation is not complete (potentially other repositories should have been updated as well but have not been), it will leave your persisted data part of the operation in an incoherent state (I wish you good luck to rollback each changes). Whereas if you only use a single UnitOfWork for the operation, if it fails before completing (before reaching the end of the action method), then no data is updated at all part of the operation, your data store stays clean (and it also does a single round trip to the DB, in a single transaction for changes done accross all repositories).

Design and Approach

Define an generic repository type interface, containing very basic atomic operations

public interface IRepository<T> where T : class
{
    IQueryable<T> AsQueryable();
 
    IEnumerable<T> GetAll();
    IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
    T Single(Expression<Func<T, bool>> predicate);
    T SingleOrDefault(Expression<Func<T, bool>> predicate);
    T First(Expression<Func<T, bool>> predicate);
    T GetById(int id);
 
    void Add(T entity);
    void Delete(T entity);
    void Attach(T entity);
}

Define an unit of work interface , containing all the generic repositories being part of the unit of work, along with a single Commit() method used to persist all changes done in the repositories to the underlying data store

public interface IUnitOfWork
{
    IRepository<Organiazation> OrderRepository { get; }
    IRepository<Employee> CustomerRepository { get; }
    
    void Commit();
}

Employee and Organization are pure POCO classes typical entity framework entities

Add class implementing the abstract generic repository, which just delegates all calls to the associated Entity Framework DbSet

public class EntityFrameworkRepository<T> : IRepository<T>
                                   where T : class
 {
     private readonly DbSet<T> _dbSet;
 
     public EntityFrameworkRepository(DbSet<T> dbSet)
     {
         _dbSet = dbSet;
     }
 
        #region IGenericRepository<T> implementation
 
     public virtual IQueryable<T> AsQueryable()
     {
         return _dbSet.AsQueryable();
     }
 
     public IEnumerable<T> GetAll()
     {
         return _dbSet;
     }
 
     public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
     {
         return _dbSet.Where(predicate);
     }
 
     public T Single(Expression<Func<T, bool>> predicate)
     {
         //TODO: To Be Implemented
         throw new NotImplementedException();
     }
 
     public T SingleOrDefault(Expression<Func<T, bool>> predicate)
     {
         //TODO: To Be Implemented
         throw new NotImplementedException();
     }
 
     public T First(Expression<Func<T, bool>> predicate)
     {
         //TODO: To Be Implemented
         throw new NotImplementedException();
     }
 
     public T GetById(int id)
     {
         //TODO: To Be Implemented
         throw new NotImplementedException();
     }
 
     public void Add(T entity)
     {
         //TODO: To Be Implemented
         throw new NotImplementedException();
     }
 
     public void Delete(T entity)
     {
         //TODO: To Be Implemented
         throw new NotImplementedException();
     }
 
     public void Attach(T entity)
     {
         //TODO: To Be Implemented
         throw new NotImplementedException();
     }
        #endregion
 }

Add class implementing IUnitOfWork and also inherits from DbContext (EF Code First unit of work).
It contains DbSets, which can be seen as repositories from EF point of view (in fact in EF Code First, you can substitute in your mind the word “Unit Of Work” with “DbContext” and “Repository” with “DbSet”).
The constructor just instantiate all the repositories by passing them the corresponding DbSet in their constructor. This can be improved by instantiating repositories only when they are accessed. Indeed if your unit of work contains 20 repositories and your controller is just going to use one, this is a lot of useless instantiation.

public class EntityFrameworkUnitOfWork : DbContextIUnitOfWork
 {
     private readonly EntityFrameworkRepository<Organization> _organizationRepo;
     private readonly EntityFrameworkRepository<Employee> _employeeRepo;
 
     public DbSet<Organization> Organizations { getset; }
     public DbSet<Employee> Employees { getset; }
 
     public EntityFrameworkUnitOfWork()
     {
         _organizationRepo = new EntityFrameworkRepository<Organization>(Organizations);
         _employeeRepo = new EntityFrameworkRepository<Employee>(Employees);
     }
 
        #region IUnitOfWork Implementation
 
     public IRepository<Organization> OrganizationRepository
     {
         get { return _organizationRepo; }
     }
 
     public IRepository<Employee> EmployeeRepository
     {
         get { return _employeeRepo; }
     }
 
     public void Commit()
     {
         this.SaveChanges();
     }
 
        #endregion
 }

Now if you need to implement another provider, let’s say “InMemory” (usefull for unit testing) all you have to do is to create two other classes InMemoryRepository and InMemoryUnitOfWork

Let’s say your HomeController needs to access all three different repositories.
With the old design, your HomeController constructor signature would have looked as

public HomeController(IEmployeeRepository empRepo, IOrganizationRepository orgRepo)
        { 
            
        }

And of course new repository to be used by HomeController, means new parameter + new private field + new binding in DI container.

With the improved design, now the signature looks much cleaner

public HomeController(IUnitOfWork unitOfWork)
        { 
        
        }

If we add new repositories that we want to use in the controller we don’t have to change anything in the controller class, nor bindings in DI container. We can just use the new repository directly from the controller through the unit of work.
No more thinking about which repositories should the controller have access too and customizing the constructor as such. Now all controllers constructors needing to access repositories just need a single unitOfWork parameter.

On DI container side, all that is needed is to bind the abstract IUnitOfWork to the desired provider implementation (EF, InMem, other …). You’ll also want to make sure that the dependency is created in a “per request scope” (considering your DI container allow this), meaning that a single unit of work will be instantiated per request and not each time the decency is required.

Let’s say you need in multiple places in your client code to run a complex query on a specific repository (IEmployeeRepository). Through the old design it’s relatively straightforward, you would just define a method in IEmployeeRepository and implement it for all the concrete providers (what a pain !).
However with the improved design we can’t add this method to IGenericRepository.

Extension methods can help in this scenario

Advertisements

Factory and Abstract Factory…….

  • Factory method is a single method, and an abstract factory is an object.
  • Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation. Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition.
  • Factory Method is used to create one product only but Abstract Factory is about creating families of related or dependent products.
  • Factory Method pattern exposes a method to the client for creating the object whereas in case of Abstract Factory they expose a family of related objects which may consist of these Factory methods.
  • Factory Method pattern hides the construction of single object where as Abstract factory method hides the construction of a family of related objects. Abstract factories are usually implemented using (a set of) factory methods.
  • Abstract Factory pattern uses composition to delegate responsibility of creating object to another class while Factory design pattern uses inheritance and relies on derived class or sub class to create object.
  • The idea behind the Factory Method pattern is that it allows for the case where a client doesn’t know what concrete classes it will be required to create at runtime, but just wants to get a class that will do the job while Abstract Factory pattern is best utilized when your system has to create multiple families of products or you want to provide a library of products without exposing the implementation details.

Factory Pattern Example

 

public interface IVehicle
 {
     void Start();
     void Drive();
     void Stop();
 }
 
 public class Car : IVehicle
 {
 
     public void Start()
     {
         Console.WriteLine("Car Started");
     }
 
     public void Drive()
     {
         Console.WriteLine("Car Driving");
     }
 
     public void Stop()
     {
         Console.WriteLine("Car Stopped");
     }
 }
 
 public class Suv : IVehicle
 {
 
     public void Start()
     {
         Console.WriteLine("Suv Started");
     }
 
     public void Drive()
     {
         Console.WriteLine("Suv Driving");
     }
 
     public void Stop()
     {
         Console.WriteLine("Suv Stopped");
     }
 }
 
 public enum VehicleType
 { 
     Car,
     Suv
 }
 public class VehicleFactory
 {
     public static IVehicle GetVehicle(VehicleType vehicleType)
     {
         IVehicle vehicle;
         switch (vehicleType)
         {
             case VehicleType.Car:
                 vehicle = new Car();
                 break;
             case VehicleType.Suv:
                 vehicle = new Suv();
                 break;
             defaultreturn null;
         }
         return vehicle;
     }
 }

Client Consuming Code looks like

class Program
{
    static void Main(string[] args)
    {
        IVehicle vehicle = VehicleFactory.GetVehicle(VehicleType.Car);
        vehicle.Start();
        vehicle.Drive();
        vehicle.Start();
        Console.ReadLine();
    }
}

Source Code can be downloaded from Here

Abstract Factory Example

public class Car : IVehicle
{
 
    public virtual void Start()
    {
        Console.WriteLine("Car Started");
    }
 
    public virtual void Drive()
    {
        Console.WriteLine("Car Driving");
    }
 
    public virtual void Stop()
    {
        Console.WriteLine("Car Stopped");
    }
}
 
public class HondaAccord : Car
{
    public override void Start()
    {
        Console.WriteLine("Honda Accord Started");
    }
 
    public override void Drive()
    {
        Console.WriteLine("Honda Accord Driving");
    }
 
    public override void Stop()
    {
        Console.WriteLine("Honda Accord Stopped");
    }
}
 
public class HondaCrv : Suv
{
    public override void Start()
    {
        Console.WriteLine("Honda Crv Started");
    }
 
    public override void Drive()
    {
        Console.WriteLine("Honda Crv Driving");
    }
 
    public override void Stop()
    {
        Console.WriteLine("Honda Crv Stopped");
    }
}
 
public class ToyotaCorolla : Car
{
    public override void Start()
    {
        Console.WriteLine("Toyota Corolla Started");
    }
 
    public override void Drive()
    {
        Console.WriteLine("Toyota Corolla Driving");
    }
 
    public override void Stop()
    {
        Console.WriteLine("Toyota Corolla Stopped");
    }
}
 
public class ToyotaRav4 : Suv
{
    public override void Start()
    {
        Console.WriteLine("Toyota Rav4 Started");
    }
 
    public override void Drive()
    {
        Console.WriteLine("Toyota Rav4 Driving");
    }
 
    public override void Stop()
    {
        Console.WriteLine("Toyota Rav4 Stopped");
    }
}
 
public class Suv : IVehicle
{
 
    public virtual void Start()
    {
        Console.WriteLine("Suv Started");
    }
 
    public virtual void Drive()
    {
        Console.WriteLine("Suv Driving");
    }
 
    public virtual void Stop()
    {
        Console.WriteLine("Suv Stopped");
    }
}
public abstract class VehicleFactory
{
    public abstract IVehicle GetVehicle(VehicleType vehicleType);
 
    public static VehicleFactory GetFactory(MakeType make)
    {
        VehicleFactory vehicleFactory;
        switch (make)
        {
            case MakeType.Honda:
                vehicleFactory = new HondaFactory();
                break;
            case MakeType.Toyota:
                vehicleFactory = new ToyotaFactory();
                break;
            defaultreturn null;
        }
        return vehicleFactory;
    }
    
}
 
public class ToyotaFactory : VehicleFactory
{
    public override IVehicle GetVehicle(VehicleType vehicleType)
    {
        IVehicle vehicle;
        switch (vehicleType)
        {
            case VehicleType.Car:
                vehicle = new ToyotaCorolla();
                break;
            case VehicleType.Suv:
                vehicle = new ToyotaRav4();
                break;
            defaultreturn null;
        }
        return vehicle;
    }
}
 
public class HondaFactory : VehicleFactory
{
    public override IVehicle GetVehicle(VehicleType vehicleType)
    {
        IVehicle vehicle;
        switch (vehicleType)
        {
            case VehicleType.Car:
                vehicle = new HondaAccord();
                break;
            case VehicleType.Suv:
                vehicle = new HondaCrv();
                break;
            defaultreturn null;
        }
        return vehicle;
    }
}
 
public enum VehicleType
{
    Car,
    Suv
}
 
public enum MakeType
{
    Toyota,
    Honda
}

Client Consuming Code looks like

class Program
{
    static void Main(string[] args)
    {
        VehicleFactory factory = VehicleFactory.GetFactory(MakeType.Honda);
        IVehicle vehicle = factory.GetVehicle(VehicleType.Car);
        vehicle.Start();
        vehicle.Drive();
        vehicle.Stop();
        Console.ReadLine();
    }
}

Source Can be downloaded from Here

Strategy Pattern with example

Strategy pattern defines a family of algorithms, encapsulates each one of them and makes them interchangeable

  • Family of Algorithms– The definition says that the pattern defines the family of algorithms- it means we have functionality (in these algorithms) which will do the same common thing for our object, but in different ways.
  • Encapsulate each one of them– The pattern would force you to place your algorithms in different classes (encapsulate them). Doing so would help us in selecting the appropriate algorithm for our object.
  • Make them interchangeable – The beauty with strategy pattern is we can select at run time which algorithm we should apply to our object and can replace them with one another

For example we need to develop a simple shipping cost calculation service where the calculation will depend on the type of the carrier: FedEx, UPS, DHL and USPS.

public class Address
{
    public string ContactName { getset; }
    public string AddressLine1 { getset; }
    public string AddressLine2 { getset; }
    public string AddressLine3 { getset; }
    public string City { getset; }
    public string Region { getset; }
    public string Country { getset; }
    public string PostalCode { getset; }
}
 
 
public enum ShippingOptions
{
    UPS = 10,
    FedEx = 20,
    USPS = 30,
    DHL = 40
}
 
public class Order
{
    public ShippingOptions ShippingMethod { getset; }
    public Address Destination { getset; }
    public Address Origin { getset; }
}
 
public class ShippingCostCalculatorService
{
    public double CalculateShippingCost(Order order)
    {
        switch (order.ShippingMethod)
        {
            case ShippingOptions.FedEx:
                return CalculateForFedEx(order);
            case ShippingOptions.UPS:
                return CalculateForUPS(order);
            case ShippingOptions.USPS:
                return CalculateForUSPS(order);
            case ShippingOptions.DHL:
                return CalculateForDHL(order);
            default:
                throw new Exception("Unknown carrier");
 
        }
    }
 
    double CalculateForDHL(Order order)
    {
        return 4.00d;
    }
 
    double CalculateForUSPS(Order order)
    {
        return 3.00d;
    }
 
    double CalculateForUPS(Order order)
    {
        return 4.25d;
    }
 
    double CalculateForFedEx(Order order)
    {
        return 5.00d;
    }
}

It is perfectly reasonable that we may introduce a new carrier in the future, say XYZ. If we pass an order with this shipping method to the CalculateShippingCost method then we’ll get an exception. We’d have to manually extend the switch statement to account for the new shipment type. In case of a new carrier we’d have to come back to this domain service and modify it accordingly. That breaks the Open/Closed principle of SOLID: a class is open for extensions but closed for modifications. In addition, if there’s a change in the implementation of one of the calculation algorithms then again we’d have to come back to this method and modify it. That’s generally not a good practice: if you make a change to one of your classes, then you should not have to go an modify other classes and public methods just to accommodate that change. Methods that calculate the costs are of course ridiculously simple in this demo – in reality there may well be calls to other services, the weight of the package may be checked etc., so the ShippingCostCalculatorService class may grow very large and difficult to maintain. The calculator class becomes bloated with logic belonging to UPS, FedEx, DHL etc, violating the Single Responsibility Principle. The service class is trying to take care of too much. The solution is basically to create a class for each calculation – we can call each implemented calculation a strategy. Each class will need to implement the same interface. If you check the calculation methods in the service class then the following interface will probably fit our needs:

public interface IShippingStrategy
{
    double Calculate(Order order);
}

Next we will implement strategies

public class USPSShippingStrategy : IShippingStrategy
{
    public double Calculate(Order order)
    {
        return 3.00d;
    }
}
 
public class UpsShippingStrategy : IShippingStrategy
{
    public double Calculate(Order order)
    {
        return 4.25d;
    }
}
 
 
public class FedexShippingStrategy : IShippingStrategy
{
    public double Calculate(Order order)
    {
        return 5.00d;
    }
}
 
public class DHLShippingStrategy : IShippingStrategy
{
    public double Calculate(Order order)
    {
        return 4.00d;
    }
}

The cost calculation service is now ready to accept the strategy from the outside. The new and improved service looks as follows:

public class ShippingCostCalculatorServiceWithStrategy
{
    private readonly IShippingStrategy _shippingStrategy;
 
    public ShippingCostCalculatorServiceWithStrategy(IShippingStrategy shippingStrategy)
    {
        _shippingStrategy = shippingStrategy;
    }
 
    public double CalculateShippingCost(Order order)
    {
        return _shippingStrategy.Calculate(order);
    }
}

You can now implement the IShippingStrategy as new carriers come into the picture and the calculation service can continue to function without knowing anything about the concrete strategy classes. The concrete strategy classes are self-containing, they can be tested individually and they can be mocked

Attached is the source code over here

Why is composition favored over inheritance

Object-Oriented Programing (OOP) has too well known candidates for the reuse of functionality: Inheritance (whitebox reuse) and Composition (blackbox reuse). Just to revise, composition and Inheritance are ways to reuse code to get additional functionality. In Inheritance, a new class, which wants to reuse code, inherit an existing class, known as super class. This new class is then known as sub class. On composition, a class, which desire to use functionality of an existing class, doesn’t inherit, instead it holds a reference of that class in a member variable, that’s why the name composition. Inheritance and composition relationships are also referred as IS-A and HAS-A relationships. Because of IS-A relationship, an instance of sub class can be passed to a method, which accepts instance of super class. This is a kind of polymorphism, which is achieved using Inheritance. A super class reference variable can refer to an instance of sub class. By using composition, you don’t get this behavior, but still it offers a lot more to tild the balance in its side.

One reason of favoring Composition over Inheritance in Java is fact that Java doesn’t support multiple inheritance. Since you can only extend one class in Java, but if you need multiple functionality like e.g. for reading and writing character data into file, you need Reader and Writer functionality and having them as private members makes your job easy that’s composition.

Composition offers better testability of a class than Inheritance. If one class is composed of another class, you can easily create Mock Object representing composed class for sake of testing. Inheritance doesn’t provide this luxury. In order to test derived class, you must need its super class. Since unit testing is one of the most important thing to consider during software development, especially in test driven development, composition wins over inheritance

Though both Composition and Inheritance allows you to reuse code, one of the disadvantage of Inheritance is that it breaks encapsulation. If sub class is depending on super class behavior for its operation, it suddenly becomes fragile. When behavior of super class changes, functionality in sub class may get broken, without any change on its part

Example
Lets say we are writing simulation software for Rocket Launching systems which are to be supplied to different countries. Now these different countries can use them as they want it. The code for our launching system is below:

public class Launcher 
{ 
    public bool LaunchMissile() 
    { 
        Console.WriteLine("Missile launched"); 
        return true; 
    }
 
}
public class SufraceToAirMissileLauncher : Launcher
{
 
}

Now, country A uses this code to launch missile as follows:

static void Main(string[] args) 
{ 
    SufraceToAirMissileLauncher staLauncher = new SufraceToAirMissileLauncher(); 
    bool isLaunched = staLauncher.LaunchMissile();
    Console.ReadLine();
}

This is how Inheritance is used. The various launchers can reuse the base Launcher class code to launch missile.

The same thing can be achieved by using Composition where base class functionality is encapsulated inside the main concrete class. The code for that is below:

public class SufraceToAirMissileLauncher 
{ 
    private Launcher launcher = new Launcher(); 
    public bool LaunchMissile() 
    { 
        return launcher.LaunchMissile(); 
    } 
}

The client UI code remains the same.

Now due to our superb code, our patented launching software had become famous and another country B wants to use it. But they had a condition that instead of launching the missile through base class they would want to get an instance of a missile. Now it’s up to them what they want to do with it. They might add some nuclear material on it or modify it to increase its range or do whatever they might like. So another Missile object comes into the picture.

public class Missile 
{ 
    private bool isLaunched; 
    public bool IsLaunched 
    { 
        get
        {
            return isLaunched; 
        } 
        set 
        { 
            isLaunched = value; 
        } 
    } 
    public Missile(bool isLaunched) 
    { 
        IsLaunched = IsLaunched;
    } 
}

And the base class function has changed to:

public class Launcher
{
    public Missile LaunchMissile() 
    { 
        Console.WriteLine("Missile returned"); 
        return new Missile(true); 
    }
 
}

Now it returns a missile instead of launching it. So now if we rely on inheritance, the client code of country A would break since the method signature has changed from what is being used in its UI. However, if the country A had used composition instead, the code will not break. Only the derived class function would need to accommodate the new changed behavior of the base class. To accommodate this, we need to change our derived class code function “LaunchMissile” as:

public class SufraceToAirMissileLauncher
{
    private Launcher launcher = new Launcher(); 
    public bool LaunchMissile() 
    { 
        Missile missile = launcher.LaunchMissile(); 
        return missile.IsLaunched; 
    } 
}

Hence, the client code of country A would still work:

static void Main(string[] args) 
{ 
    SufraceToAirMissileLauncher staLauncher = new SufraceToAirMissileLauncher(); 
    bool isLaunched = staLauncher.LaunchMissile();
    Console.ReadLine();
}

On the other hand country B which was insisting on getting a missile would still get missile from the base class.
So through this simple example we see how the composition is favored over inheritance to maintain compatibility and where there is a possibility that the functionality might change in future.

Source Code

SOLID – Application Development Principles

SOLID Principles – PDF Document Well Formatted.

Source Code Can be downloaded from here

SOLID are five basic principles whichhelp to create good software architecture. SOLID is an acronym where:-

  • S stands for SRP (Single responsibility principle
  • O stands for OCP (Open closed principle)
  • L stands for LSP (Liskov substitution principle)
  • I stands for ISP ( Interface segregation principle)
  • D stands for DIP ( Dependency inversion principle)

Single Responsibility

Single Responsibility Principle states that objects should have single responsibility and all of their behaviors should focus on that one responsibility

    class Customer
    {
        public void Add()
        {
            try
            {
                // Database code goes here
            }
            catch (Exception ex)
            {
                System.IO.File.WriteAllText(@"c:\Error.txt", ex.ToString());
            }
        }
 
    }

The above customer class is doing things WHICH HE IS NOT SUPPOSED TO DO. Customer class should do customer data validations, call the customer data access layer etc , but if you see the catch block closely it also doing LOGGING activity. In simple words its over loaded with lot of responsibility.

 

With Single Responsibility Principle – Move that logging activity to some other class who will only look after logging activities.

class FileLogger
{
    public void Handle(string error)
    {
        System.IO.File.WriteAllText(@"c:\Error.txt", error);
    }
}
 
class Customer
{
    private FileLogger obj = new FileLogger();
    public virtual void Add()
    {
        try
        {
            // Database code goes here
        }
        catch (Exception ex)
        {
            obj.Handle(ex.ToString());
        }
    }
}

 

Open/Closed Principle

Open and Closed principle encourages components that are open for extension, but closed for modification.

class Customer
{
    private FileLogger obj = new FileLogger();
    public virtual void Add()
    {
        try
        {
            // Database code goes here
        }
        catch (Exception ex)
        {
            obj.Handle(ex.ToString());
        }
    }
}
 
class Customer
{
    private int _CustType;
    public int CustType
    {
        get { return _CustType; }
        set { _CustType = value; }
    }
 
    public double getDiscount(double TotalSales)
    {
 
        if (_CustType == 1)
        {
            return TotalSales - 100;
        }
        else
        {
            return TotalSales - 50;
        }
    }
}

The problem is if we add a new customer type we need to go and add one more “IF” condition in the “getDiscount” function, in other words we need to change the customer class. If we are changing the customer class again and again, we need to ensure that the previous conditions with new one’s are tested again , existing client’s which are referencing this class are working properly as before. In other words we are “MODIFYING” the current customer code for every change and every time we modify we need to ensure that all the previous functionalities and connected client are working as before. How about rather than “MODIFYING” we go for “EXTENSION”. In other words every time a new customer type needs to be added we create a new class as shown in the below. So whatever is the current code they are untouched and we just need to test and check the new classes.

class Customer
{
    private FileLogger obj = new FileLogger();
    public virtual void Add()
    {
        try
        {
            // Database code goes here
        }
        catch (Exception ex)
        {
            obj.Handle(ex.ToString());
        }
    }
 
    public virtual double getDiscount(double TotalSales)
    {
        return TotalSales;
    }
}
 
class VIPCustomer : Customer
{
    public override double getDiscount(double TotalSales)
    {
        return base.getDiscount(TotalSales) - 50;
    }
}

 

Liskov Substitution Principle

This principle states that object should be easily replaceable by the instances of their sub types without influencing the behavior and rules of the objects. Let’s continue with the same customer. Let’s say our system wants to calculate discounts for Enquiries. Now Enquiries are not actual customer’s they are just leads. Because they are just leads we do not want to save them to database for now. So we create a new class called as Enquiry which inherits from the “Customer” class. We provide some discounts to the enquiry so that they can be converted to actual customers and we override the “Add’ method with an exception so that no one can add an Enquiry to the database.

 

class Enquiry : Customer
{
    public override double getDiscount(double TotalSales)
    {
 
        return base.getDiscount(TotalSales) - 5;
    }
 
 
    public override void Add()
    {
        throw new Exception("Not allowed");
    }
}

So as per polymorphism rule my parent “Customer” class object can point to any of it child class objects i.e. “VIP”, or “Enquiry” during runtime without any issues.

So for instance in the below code you can see I have created a list collection of “Customer” and thanks to polymorphism I can add “VIP” and “Enquiry” customer to the “Customer” collection without any issues.

List<Customer> customers = new List<Customer>();
customers.Add(new VIPCustomer());
customers.Add(new Enquiry());
foreach (Customer customer in customers)
{
    customer.Add();
}

As per the inheritance hierarchy the “Customer” object can point to any one of its child objects and we do not expect any unusual behavior. But when “Add” method of the “Enquiry” object is invoked it leads to below error because our “Equiry” object does save enquiries to database as they are not actual customers. So LISKOV principle says the parent should easily replace the child object. So to implement LISKOV we need to create two interfaces one is for discount and other for database as shown below.

interface IDiscount
{
    double getDiscount(double TotalSales);
}
 
interface IDatabase
{
    void Add();
}

Now the “Enquiry” class will only implement “IDiscount” as he not interested in the “Add” method.

class Enquiry : IDiscount
{
    public double getDiscount(double TotalSales)
    {
        return TotalSales - 5;
    }
}

While the “Customer” class will implement both “IDiscount” as well as “IDatabase” as it also wants to persist the customer to the database.

class Customer : IDiscountIDatabase
{
    private FileLogger obj = new FileLogger();
    public virtual void Add()
    {
        try
        {
            // Database code goes here
        }
        catch (Exception ex)
        {
            obj.Handle(ex.ToString());
        }
    }
 
    public virtual double getDiscount(double TotalSales)
    {
        return TotalSales;
    }
}

Now there is no confusion, we can create a list of “IDatabase” interface and add the relevant classes to it. In case we make a mistake of adding “Enquiry” class to the list compiler would complain.

Interface Segregation Principle

It encourages the use of Interface but limits the size of the interface. Instead of one super class interface that contains all the behavior for an object, there should exist multiple smaller more specific interfaces

e.g. .NET has separate interface for serialization and disposing (ISerializaable and IDisposable)

Now assume that our customer class has become a SUPER HIT component and it’s consumed across 1000 clients and they are very happy using the customer class. Now let’s say some new clients come up with a demand saying that we also want a method which will help us to “Read” customer data. So developers who are highly enthusiastic would like to change the “IDatabase” interface as shown below.

But by doing so we have done something terrible, can you guess?

interface IDatabase
{
    void Add(); // old client are happy with these.
    void Read(); // Added for new clients.
}

 

If you visualize the new requirement which has come up, you have two kinds of client’s: –

Who want’s just use “Add” method. The other who wants to use “Add” + “Read”. Now by changing the current interface you are doing an awful thing, disturbing the 1000 satisfied current client’s , even when they are not interested in the “Read” method. You are forcing them to use the “Read” method. So a better approach would be to keep existing clients in their own sweet world and the serve the new client’s separately. So the better solution would be to create a new interface rather than updating the current interface. So we can keep the current interface “IDatabase” as it is and add a new interface “IDatabaseV1” with the “Read” method the “V1” stands for version 1.

interface IDatabaseV1 : IDatabase // Gets the Add method
{
    void Read();
}

You can now create fresh classes which implement “Read” method and satisfy demands of your new clients and your old clients stay untouched and happy with the old interface which does not have “Read” method.

 

class CustomerWithRead : IDatabaseIDatabaseV1
{
    public void Add()
    {
        Customer obj = new Customer();
        obj.Add();
    }
    public void Read()
    {
        // Implements logic for read
    }
}

So the old clients will continue using the “IDatabase” interface while new client can use “IDatabaseV1” interface.

IDatabase i = new Customer(); // 1000 happy old clients not touched
i.Add();
IDatabaseV1 iv1 = new CustomerWithRead(); // new clients
iv1.Read();

Dependency Inversion Principle

Components that depend on each other should interact via an abstraction and not directly with concrete implementation. Inversion of Controls Glues all these principles together. Two proper implementation for IoC are

  • Dependency Injection
  • Service Location

 

Major difference between two implementations revolves around how the dependencies are accessed

Service Locator relies on the caller to invoke and ask for dependency

Dependency injection relies on injecting the dependency in to the class through constructor, setting one of its properties or executing one of its methods.

 

In our customer class if you remember we had created a logger class to satisfy SRP. Down the line let’s say new Logger flavor classes are created.

 

class Customer : IDiscountIDatabase
{
    private FileLogger obj = new FileLogger();
    public virtual void Add()
    {
        try
        {
            // Database code goes here
        }
        catch (Exception ex)
        {
            obj.Handle(ex.ToString());
        }
    }
    public virtual double getDiscount(double TotalSales)
    {
        return TotalSales;
    }
}

Just to control things we create a common interface and using this common interface new logger flavors will be created.

interface ILogger
{
    void Handle(string error);
 
}

Below are three logger flavors and more can be added down the line.

class FileLogger : ILogger
{
    public void Handle(string error)
    {
        System.IO.File.WriteAllText(@"c:\Error.txt", error);
    }
 
}
class EverViewerLogger : ILogger
{
    public void Handle(string error)
    {
        // log errors to event viewer
    }
}
class EmailLogger : ILogger
{
    public void Handle(string error)
    {
        // send errors in email
    }
 
}

Now depending on configuration settings different logger classes will used at given moment. So to achieve the same we have kept a simple IF condition which decides which logger class to be used, see the below code.

class Customer : IDiscountIDatabase
{
    private ILogger obj;
    public virtual void Add(int exhandle)
    {
        try
        {
            // Database code goes here
        }
        catch (Exception ex)
        {
            if (exhandle == 1)
            {
                obj = new FileLogger();
            }
            else
            {
                obj = new EmailLogger();
            }
            obj.Handle(ex.Message.ToString());
        }
    }
 
    public virtual double getDiscount(double TotalSales)
    {
        return TotalSales;
    }
}

The above code is again violating SRP but this time the aspect is different, it’s about deciding which objects should be created. Now it’s not the work of “Customer” object to decide which instances to be created, he should be concentrating only on Customer class related functionalities. If you watch closely the biggest problem is the “NEW” keyword. He is taking extra responsibilities of which object needs to be created. So if we INVERT / DELEGATE this responsibility to someone else rather the customer class doing it that would really solve the problem to a certain extent. So here’s the modified code with INVERSION implemented. We have opened the constructor mouth and we expect someone else to pass the object rather than the customer class doing it. So now it’s the responsibility of the client who is consuming the customer object to decide which Logger class to inject.

class Customer : IDiscountIDatabase
{
    private ILogger logger;
    public Customer(ILogger logger)
    {
        this.logger = logger;
    }
 
    public virtual void Add()
    {
        try
        {
            // Database code goes here
        }
        catch (Exception ex)
        {
            logger.Handle(ex.ToString());
        }
    }
    public virtual double getDiscount(double TotalSales)
    {
        return TotalSales;
    }
}

So now the client will inject the Logger object and the customer object is now free from those IF condition which decide which logger class to inject. This is the Last principle in SOLID Dependency Inversion principle. Customer class has delegated the dependent object creation to client consuming it thus making the customer class concentrate on his work.

IDatabase i = new Customer(new EmailLogger());

Validations through Decorator Pattern

The decorator pattern is a common design pattern often used to add new functionality to an object dynamically. The main benefit of the decorator pattern is that the existing object’s class is not directly modified. This follows the open-closed principle in the Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion design principles, or SOLID for short.

The four participants are:

  1. Component Interface:: Interface for the objects that can have responsibilities added to it dynamically. The component interface defines the operations and properties for the component. In our example ICreditCard
  2. ConcreteComponent: Defines an object implementing Component interface. This is the object that is going to be decorated, but it doesn’t have any knowledge of decoration. The person implementing the decorator may not even have the access to the source code. The concrete component is the primary class you want to extend that implements the component interface. In our example CreditCard.
  3. Decorator: Maintains a reference to the Component object, and defines an interface that conforms to the Component interface. So it contains a reference to the base behavior, and also implements the same interface, hence can be treated as the Component itself. The client code expecting the Component will deal with Decorator without even noticing the difference. In our example CreditCardDecorator.
  4. ConcreteDecorator: This actually adds responsibility to the component. The class that inherits from Decorator and may add some additional specific functionality in the form Validations. In our example CreditCardValidatorBase and CreditCardValidator, CreditCardValidatorBase is just providing Validation functionality and provides validation rules which can be further extended by sub classes if required.

Decorator

Attached is the Source Code Sample

Validation Through Decorator Pattern