Solid Principle: Single Responsibility Principle (SRP)

So, its been quite long I have not been doing any blogging. I thought and I really would wish to start  my blogging with Azure Webjobs series but in my way of writing a student from this event asked me some questions that worth me writing this article.

SOLID principle is one of coolest and sexist topic that you as a smart developer should be aware while coding to remove code smells.

The principles that make up the acronym are as follows:

Acronym Principle Principle defined
S Single Responsibility Principle A class should have one, and only one, reason to change.
O Open/Closed Principle You should be able to extend a classes behavior, without modifying it.
L Liskov Substitution Principle Derived classes must be substitutable for their base classes.
I Interface Segregation Principle Make fine grained interfaces that are client specific.
D Dependency Inversion Principle Depend on abstractions, not on concretions.

In this post I am going to discuss about Single Responsibility Principle (SRP).

Single Responsibility Principle (SRP)

Freshers, recent graduates who don’t have industrial working experience they often mixed up responsibilities and usually prefer to write them under one single class. For this very reason, soon their All-In-One class become a big pile of mess. Those class become fragile and non-reusable. So, when new requirement appears they just can’t extend their application in an easy way. Rather they need to make changes on many places. This process is not only error-prone  but at the same time its time consuming as well.

Now, the obvious question is why they prefer or i would rather say why most of them mastered on this style. The answer is simple.

  1. Such system is easy to built and
  2. While designing the system  they did not bring one vital point in consideration i.e. “A system requirement can change over time”.

When a class has more then one responsibility it clearly indicate that the class has more then a reason for change! At its worst changes to any one of the responsibility may prevent the class to pass all the regression test. This kind of coupling leads to fragile designs that may break in unexpected ways when changed.

Let me come up with one code sample that violate this principle.

public class MailChimpReportsOverview
{
/// <summary>
/// Get MailChimp Campaign Reports
/// </summary>
public async Task<ReportOverview> OverviewAsync()
{
string method= "reports";
string server ="us12";
string endpoint = String.Format("https://{0}.api.mailchimp.com/3.0/{1}", server, method);
string content;
using (var client = new HttpClient())
{
try
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Authenticate.FeatchApiKey());
content = await client.GetStringAsync(endpoint).ConfigureAwait(false);
}
catch (Exception ex)
{
using (StreamWriter file = new StreamWriter("c:\\log.txt",true)
{
file.WriteLine(ex.ToString());
}
}
}
return JsonConvert.DeserializeObject<ReportOverview>(content);
}
}
view raw SRP violation hosted with ❤ by GitHub

The main responsibility of the above class is to Get campaign reports from mailchimp server. But as you can see the class is doing lot more then this. Inside the try block it first trying to authorize the current connection.  Once the connection is established its downloading the campaign analytic report from the specified endpoint. It also deserializing the result. In case of failure it also doing some basic logging for future diagnosis.

To solve this issue one should strive with “Single Responsibility Principle” aka SRP. It states that –

A class should have one, and only one, reason to change.

This means you should break your All-In-One class into so many pieces of class unless each of the class holds only one(single) responsibility. Now, as we all agree to break our class in such that it holds only one responsibility the next question is how do we determine if a class has more then one responsibility. Sandi Metz, the author of Practical Object-Oriented Design in Ruby (POODR) mentioned a nice trick. To describe a class if you have to use words like “and” or “or,” you’re most likely breaking the Single Responsibility Principle (SRP). If you have to use the word “and” your class has at least two responsibilities. On the other hand, If you have to use the word “or,” the class likely has more than one responsibility, and there is a good chance that these responsibilities aren’t related to one another.

In brief, anything that gives a class a reason to change can be considered as a responsibility.

Enough talk! Lets refactor the existing code base to fit in SRP.

public class MailChimpReportsOverview
{
public async Task<ReportOverview> OverviewAsync(string endpoint)
{
private FileLogger logger = new FileLogger();
string content;
using (var client = new HttpClient())
{
try
{
Authenticate.ClientAuthentication(client);
content = await client.GetStringAsync(endpoint).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.log(ex.ToString());
}
}
return JsonConvert.DeserializeObject<ReportOverview>(content);
}
}
view raw SRP Implemented hosted with ❤ by GitHub

As you can can see the above code now have only one responsibility. I have extracted other responsibility into their own class.

Extracted class shown below :

class FileLogger
{
public void Log(string exceptionMsg)
{
using (StreamWriter file = new StreamWriter("c:\\log.txt",true)
{
file.WriteLine(exceptionMsg.ToString());
}
}
}
public static class Authenticate
{
public static void ClientAuthentication(HttpClient client)
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Authenticate.FeatchApiKey());
}
}
view raw Extracted class hosted with ❤ by GitHub

Heads Up:

As you keep following the SRP, you will end up with a good number of classes. Beginner often find it little bit difficult to expose this huge number of classes to its end client. One way to deal with this issue is to add a new abstract layer, this is something beyond the scope of this article.

Summary:

Following the SRP each concrete class become very specific. It not only keeps the classes small and focused but it also makes them easier to understand.

One thought on “Solid Principle: Single Responsibility Principle (SRP)

  1. Pingback: Solid Principle : Open Closed Principle (OCP) | LearnWithShahriar

Leave a comment