Pages

Tuesday, March 16, 2010

Single Responsibility Principle



In this post, I will talk about the Single Responsibility Principle. Before I dive into this discussion, let us briefly talk about software design.

Over the years, software complexity has increased exponentially. Diverse business needs are dictating complex software design. Programmers are burdened with learning and writing better code. A programmer either has to write new software or modify an existing code. Writing new software is easy, however; modifying existing code with a bad design is both difficult to understand and refractor. The question is ‘what is a bad software design’ and how do we identify it? Well to answer it, bad design shares the following flaws:

Rigid: Changes are hard to make
Fragile: Fixing something breaks something else
Immobile: Extension to existing code is difficult

A code is Rigid when making changes is difficult. Usually you find yourself scratching your head when tasked to change some code written by another programmer. This could be due to two reasons. First, there is no proper flow between classes/modules or second, proper coding standards (such as design patterns) are not followed. Such code is always difficult to understand and more difficult to change.

A code is Fragile when making a change breaks something else. How many times has it happened that your boss told you to fix something (which you did proudly) but discovered later that you broke something else?

Finally a code is Immobile when it cannot be reused or is difficult to extend. For example, it is always advisable to design a generic Data Access Layer (DAL) which can connect to any database. However, if the DAL is written targeting a specific database and the top management decides to use a different database later on, the programmer ends up cursing himself for writing a general DAL.

The above design issues can be avoided by adhering to proven best practices in the software industry. This is where design patterns come into play. In this post we will talk about ‘Single Responsibility Principle (SRP)’. Following posts will also discuss:

• Open Closed Principle (OCP)
• Liskov Substitution Principle (LSP)
• Dependency Inversion Control (DIC)



Single Responsibility Principle (SRP)

Single Responsibility Principle states that ‘a class or module should have only one responsibility’ where a responsibility is a ‘reason for change’. In plain English this means that a class should serve a single purpose (responsibility). Only the responsibility dictates a change in the class. If a class has more than one responsibility then it will lead to bad design later on. Changes made to a class should not affect others. This principle follows Dijkstra’s ‘Separation of Concern (SOC)’ principle.

Let me demonstrate this concept with a simple example. Consider the following class:


public class Employee {

public EmployeeDTO GetEmployee (int employeeID)
{
// perform database lookup and get the employee
}

public double CalculateSalary (int employeeID)
{
// perform database lookup and calculate salary
}
}


The above Employee class is serving two purposes. First, it returns an employee and second it calculates the salary of the employee. The first function is justified, however; the Employee class should know anything about calculating the salary of an employee. This means every time the salary calculating formula changes, the Employee has to be modified. This process should be handled by a separate class. So the above code can be modified as following:

public class Payroll 
{
public double CalculateSalary (int employeeID)
{
// calculate and return the employee salary
}
}

public class Employee {

public EmployeeDTO GetEmployee (int employeeID)
{
// perform database lookup and get the employee
}

public double CalculateSalary (int employeeID)
{
Payroll pay = new Payroll ();
return pay.CalculateSalary (employeeID);
}
}


I am sure you can spot the change in the above code. The responsibility of calculating the salary is now handled by the Payroll class. The Employee class is no longer concerned about how the salary is calculated. It just invokes a method of the Payroll class and gets the required results. The Payroll class can be changed without affecting the Employee class and vice versa.

One may argue that the Single Responsibility Principle can result in a plethora of classes. The answer is yes it can. However, having more classes which are simple to manage is better than having a few but complex classes. Managing complex classes is always a burden on the programmer. Simple classes make refracting easy for any future changes.

I hope this post has been helpful to under the Single Responsibility Principle. In the following posts, I will discuss some more principles mentioned above. So stay tuned for more.

No comments:

Post a Comment