SOLID Principles - Single Responsibility Principle

The first of the SOLID Principles to cover is the letter S which is the Single Responsibility Principle (SRP).

SOLID

What is the Single Responsibility Principle (SRP)?

The Single Responsibility Principle (SRP) states that “A class should have one, and only one, reason to change.” We are being encouraged to design software so that every class we create is focused on one responsibility in our application. Please don’t interpret this to imply that a class should only have a single method. It’s perfectly acceptable to have multiple methods, just that they should all be related.

An Example

To learn about the Single Responsibility Principle (SRP) lets create an example.

You’re building a new online store and are going to create the Order class. This Order class will obviously hold information about an order.

public class Order
{
    public ICollection<Item> Items { get; set; }
    public Customer Customer { get; set; }

    public void PlaceOrder()
    {
        try
        {
            using (var dbContext = new DbContext())
            {
                dbContext.Order.Add(this);
            }
        }
        catch (Exception ex)
        {
            System.IO.File.WriteAllText(@"c:\log.txt", ex.ToString());
        }
    }
}

Do we see something wrong with this code?

Well the PlaceOrder function has implimented code that is not part of the primary purpose. It has code for adding the order to the database and logging errors.

Working with the database and logging errors shouldn’t be part of this class.

Lets refactor this code to fix this.

public class OrderRepository
{
    public void AddOrder(Order order)
    {
        using (var dbContext = new DbContext())
        {
            dbContext.Order.Add(order);
        }
    }
}

public class Logger
{
    public void Log(Exception ex)
    {
        System.IO.File.WriteAllText(@"c:\log.txt", ex.ToString());
    }
}

public class Order
{
    public ICollection<Item> Items { get; set; }
    public Customer Customer { get; set; }

    public OrderRepository orderRepository = new OrderRepository();
    public Logger Logger = new Logger();

    public void PlaceOrder()
    {
        try
        {
            orderRepository.AddOrder(this);
        }
        catch (Exception ex)
        {
            Logger.Log(ex);
        }
    }
}

We’ve moved the code for working with the database and logging to external classes. This allow the code in the Order class to be focused on Order activites and delegate non-order functioanlity to be handled by other classes that will only focus on their respective responsibility.

Should you need to change how logging works, you know you can safely change that code without breaking functionality and best of all you will only need to do it in one spot as opposed to searching through all your codebase to update how logging works.

Avatar
Alan P. Barber
Software Developer, Computer Scientist, Scrum Master, & Crohn’s Disease Fighter

I specialize in Software Development with a focus on Architecture and Design.

comments powered by Disqus
Next
Previous

Related