S is for Single Responsibility Principle

I'm currently taking a look at some design basics and starting with the SOLID principles, part one is of course the Single Responsibility Principle.

"Each class should have a single reason to change."

Let’s explore what ‘reason to change’ actually means.

If we've got a class that performs more than one function then it might have more than one reason to change. So for example if we have a Rockstar class:

public class Rockstar
{
	public void Dance()
	{
		//Implementation of rockstar dancing
	}
	public void Sing()
	{
		//Implementation of rockstar singing
	}
}

The rockstar can both sing and dance, the implementations of singing and dancing are both inside the class. We’ve got two reasons to change, there can be a change to dancing and there can be a change to singing. According to the rule this is bad.

So why is it bad?

A class is more robust if it only has one responsibility. If it’s trying to do fewer things then it tends to be less complicated and when the time comes to make a change you’re less likely to break things.

And how do we fix it?

Implementations for Dancing and Singing shouldn’t be inside the Rockstar class, instead we should have classes to implement rockstar dancing and singing which are referenced by the Rockstar class;

public class Rockstar
{
    private IDancer RockstarDance = new RockstarDance();
    private ISinger RockstarSing = new RockstarSing();
    public void Dance()
    {
        RockstarDance.Dance();
    }
    public void Sing()
    {
        RockstarSing.Sing();
    }
}

public class RockstarDance : IDancer
{
    public void Dance()
    {
        //implementation for rockstar dancing
    }
}

public class RockstarSing : ISinger
{
    public void Sing()
    {
        //implementation for rockstar singing
    }
}

We've taken the implementations for singing and dancing out of the Rockstar class and into classes that have single responsibilities. Importantly we've also added interfaces which gives us a little more flexibility and is good for testing.