Monday, April 20, 2015

Single Responsibility Principle In Detail

Shout it kick it on DotNetKicks.com
Single Responsibility Principle – is one of the SOLID principles defined by Rober.C.Martin. Principle says “Implementation (Class/ Function) should perform only one task or Implementation (Class/Function) should change for only one reason”.

So in simple word it says “Whatever developer implements (Class/Function) in code during development should perform only one task and developer should only have one reason to change implementation (Class/Function).”

Wrong interpretation of the Principle:


Most of developer interprets it as “Class should perform only one task”. But it’s not only class, function you implement in code during development should also need to perform only one task. So one should interpret it as “Implementation(Class/Function) should perform only one task”

Real Life Example of not following Single Responsibility Principle


What happens when one can do more than one tasks. Below is image example of it



One can able to perform multiple tasks there is no question in it, but it’s not going to provide quality /better output. So to get good quality/better output of work, one should do one task at time.

Example of not following Principle in Application Development


In programming i.e. during developing code as below Order class not following principle

Public class OrderManager
{
 Public List<string> ValidateOrder()
 {
  //Code for validation
 }

 Public bool SaveOrder(OrderInfo order)
 {
  //Code for saving order
 } 

 Public void NotifyCustomer()
 {
  //Code for notification 
 }
}

Above order class having following responsibility
  1. ValidateOrder - Validating Order placed by customer and return error message if any
  2. SaveOrder – Saving Order placed by Customer and return true/false
  3. NotifyCustomer – Notify customer order is placed 

Method not following principle


Public int SumOfAllCustomerOrder(int customerId)
{
            int sum =0;
  var query= “Select * from order where customerid =” + customerid;;
           //query orders
          foreach(Order in OrderCollection)
          {
  If(Order.Items.Count > 5)
             Sum += Order.Price;            
          } 
  return sum;
}

Above method having following responsibility
  1. Method first all the order
  2. It went through all order in collection and do some of that 

Following Single Responsibility Principle


To make class or function to following Single Responsibility Principle, divide responsibility by creating new classes or function

Public Class OrderValidator
{
   Public List<string> Validate(Order order) { //code for validation}
}

Public Class Notifier
{
   Public void Notify(string emailId) { //code for notification}
}

Public Class OrderManager
{
  Private readonly OrderValidator orderValidator;
  Private readonly Notifier notifier;
  Public OrderManager(OrderValidator oValidator, Notifier nFier)
  {
 orderValidator = oValidator;
   notifier = nFier;
  }

   Public bool SaveOrder(OrderInfo orderInfo) 
  { 
     //Validate order 
  orderValidator.Validate(orderInfo);
        //code for saving order //this might be call to repository to save order 
        //notify after successful saving
        notifier.Notify(orderInfo.EmailId)
  }

   Public List<orderinfo> GetOrders(int customerId) { //code for getting order by cusotmerid}
}

Above code shows the three classes which is having only single responsibility to perform.

For method it will be like

Public List<orderinfo> GetOrder(int customerId)
{
            int sum =0;
  var query= “Select * from order where customerid =” + customerid;;
           //query orders
          return ordercollection;
}

Public int SumOfAllCustomerOrder(int customerId)
{
          var OrderCollection = GetOrder(customerId);
          foreach(Order in OrderCollection)
          {
  If(Order.Items.Count > 5)
             Sum += Order.Price;            
          } 
  return sum;
}

Note:

Following Single Responsibility doesn’t mean one can create class with one method.

Disadvantage of not following Single Responsibility Principle


In programming if developer write a class/function that performs more than one task always cause problem in providing good quality. Following problems related to class perform more than one task
  1. It’s very difficult for the other developer (i.e. who is not having any knowledge of class) to understand class/function.
  2. It’s difficult for the other developer to maintain the class/function or change the class/function.
  3. Writing test cases for the class/function also becomes difficult. 

How to Identify not following Single Responsibility Principle


  1. Try to write one line description of the class or method, if description contains word like (and, or, but, if). Example description of the class listed above where not following single resposiblity is: 
  2. “Order class that performs order saving, notification to customer and validate order”.
  3. Class constructor taking more than three argument or Method contains too many parameters.
  4. Class or Method is too long implementation.
  5. Class is low cohesive. Read more about cohesion : http://en.wikipedia.org/wiki/Cohesion_%28computer_science%29


Ref. From: Clean code – Robert .C. Martin