Single Responsibility Principle (SRP) - S.O.L.I.D. Framework

The S.O.L.I.D. Framework and its principles are an approach to deal with the most software design issues. Robert C. Martin, or better known as Uncle Bob in the industry, created those principles in the 1990’s. In this and the next blog posts I am covering every single principle in its own dedicated post, starting with the Single Responsibility Principle (SRP) here.

The SRP simplified says “Every software module should have only one reason to change“.

What does this means?

It means that a class should only have one job to do and it should be related to a single purpose, but a single class can have multiple methods and members and it’s not restricted to one single function. The complete opposite of the SRP would be an implemenation like an swiss army knife – a object who has all methods and functions in it and one change would effect all the other parts.

Giant Swiss Army Knife

If we look at the following example within the AccountManager there are two methods. The first registers an account and calls the second method which will send an email. But the SendEmail Method has nothing to do with the Account in general – so there we have an violation of the Single Responsibility Principle.

 public class AccountManager
    {
        public void Register(string name, string email, string password)
        {
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name));
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(email));
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(password));

            var account = new Account(name, email, password);

            SendEmail(new Email("confirmation@registration.com", email) { Subject = "Confirmation of your Registration." });
        }

        public bool SendEmail(Email message)
        {
            _smtpClient.Send(message);
        }
    }

By moving the EmailService to its own class we can minimize the responsibility of the AccountManager class to its origin – to manage the Account without any other methods or responsibilities.

public class AccountManager
    {
        EmailService emailservice;

        public AccountManager(EmailService emailservice)
        {
            this.emailservice = emailservice;
        }

        public void Register(string name, string email, string password)
        {
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name));
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(email));
            Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(password));
            
            var account = new Account(name, email, password);

            this.emailservice.SendEmail(new Email("confirmation@registration.com", email) { Subject = "Confirmation of your Registration." });
        }        
    }

    public class EmailService
    {
        SmtpClient smtpClient;

        public EmailService(SmtpClient smtpClient)
        {
            this.smtpClient = smtpClient;
        }

        public bool SendEmail(Email message)
        {
            smtpClient.Send(message);
        }
    }

This is an very easy way to show the meaning and implemenation of the SRP.