SOLID Design Principles - Single Responsibility Principle

SOLID Design Principles - Single Responsibility Principle

In Object Oriented Programming paradigm, SOLID refers to a set of (class) design methodologies that are used to "structure" your (OOP) code more efficiently to make it more understandable, flexible and maintainable. 

No article about SOLID principles can be written without giving the due credit to Uncle Bob or Robert C. Martin, who has been advocating and promoting these principles since late 90s.

SOLID is an acronym for 

  • S - Single Responsibility Principle
  • O - Open/Closed Principle
  • L - Liskov Substitution Principle
  • I - Interface Segregation Principle
  • D - Dependency Inversion Principle

In this first part, I will share my knowledge about the first principle Single Responsibility, also referred to as "SRP", and see what IT IS and what IT IS NOT.

SRP is one principle which is really easy to explain but definitely confusing/difficult to implement. Lets see why. As per Uncle Bob, Single Responsibility Principle states that 

"A class should have One and ONLY One responsibility"

Really Easy, Eh? 

However, a lot of developers get confused by this definition of SINGLE Responsibility. So, Lets first try to summarize what SRP IS NOT.

1. Some developers have the opinion that each Public method of a class represents ONE Responsibility. However, if we agree to that, implementing SRP would mean that each class in our application should only have a single method, which is not a good way to structure classes. 

2. SRP does not have to do anything with the size of your class in terms of lines of code. (Although, it will definitely reduce the size of your classes, substantially, when implemented in a right way.)

What IT IS

Well, because of some degree of ambiguity in its definition, different people interpret the SRP in their own ways. To make it unambiguous, Robert C. Martin, later defined it as 

"A class should have only one reason to change."

Makes Sense? Nah. Still Ambiguous.

Understanding Cohesion

It is very important to understand about Cohesion to better understand about SRP. Cohesion can be described as the relationship of all the Data and Methods of a class and the measure of the reason to put them together.

To simplify, it helps us to understand - to what extent a method (or for that matter Data) is related to the rest of the code in the class and what purpose it serves to put that method in that class.

Lets look at some code. YAY... Consider the following example. (I have omitted the detailed code for brevity)

Class Person

{

	string fName,

	string lName,

	string mobile,

	.

	.

	

	//constructor

	public void Person(necessary arguments go here)

	{

		//Initialize Data members

	}

	

	public Person GetPersonDetails(decimal Id)

	{

		//Create DbConnection

		//SQL SELECT where PersonID = Id;

		//Fill values in Person object;

		//return Person;

	}



	public decimal SavePerson(Person objPerson)

	{

		//Create DBConnection

		//Write INSERT Query to save details passed in objPerson.

		//return ID on success

		//show Message to User	

	}	



	public ArrayList<Person> GetPersons(string condition)

	{

		//Create DbConnection

		//SQL SELECT where Condition;

		//Fill values in Person objects using foreach;

		//return Arraylist<Person>;

	}



	public boolean ResetPassword(string password)

	{

		//Create DBConnection

		//Write UPDATE Query to update the new password

		//Create SMTP object and send Email

		//return true on success

	}

}

Many developers tend to write Such Business classes, however, this breaks the SRP at multiple occasions. Although, it seems to have a cohesive code that deals with Person object only, there are multiple reasons of change in this code. Lets analyse in detail:

1. The only responsibility or "Reason of change" for the Person class should be if we ever want to add/change a functionality of the PERSON, which may be addition of another field say "Salary" or "Department"

2. This class depends upon multiple other classes/libraries that can be a reason for change in future. 

a.) If all such business Classes handle the DBConnection (or any Database dependent code) in the business objects, a decision to change the Database will need the change in the class. 

b.) Person class uses some SMTP email server to send the Emails. If we ever think of changing or upgrading the Email Server, the Person class have to change.

c.) Person class also manipulates UI of the application by showing messages to the User. If we ever decide to change the format of the message or more commonly, go with a multilingual UI, the Person class has to change.

So, we should try to collate and envision all such reasons that may cause a change in our future design, and try to write separate classes dealing with those responsibilities. For example,

1. Our application should have a DB Class that deals with Database jargon. The reason for change of DB class will be if we ever decide to scale or change to a different Database. The rest of the classes in the application need not know about this change as long as the input and output of that class remains the same.

2. Our application should have a single Email class that encloses the logic to connect to a server and deals with Email operations.

3. Same goes for a class for Showing Messages or Logging Errors and so on.

- Do Note that all the public functions related to the Person class will still remain in Person class (Cohesion), however, we structure our code/classes in a way to create separate classes to handle responsibilities that do not Belong to the Person class. 

Benefits

The main benefit of following SRP is to reduce the effect of bugs/changes and improve the testing efficiency of our code. As said above, if a single class contains code that may change for multiple reasons, we would need to test that class and all its dependent classes, whenever the code changes because of any of those reasons.

In our Example above, all the classes using Person class will have to be tested, if any of the following happens.

1. Change in Database Connections/Servers OR

2. Change in Email Server or its configurations

3. Change in Format of UI messages or language and so on.

4. And ofcourse, the change in the Person Object itself.

Analyzing such test scenarios also helps us in understanding the responsibilities OR reasons of change for a single class. 

So, Single Responsibility Principle has to deal with how you structure your classes cohesively so that the code in that class should only be present there if it has a relation to the purpose of that class. Your code may choose to use other classes (like DB or Email) using a contract or interface but not know about any detail of that code and changing that code should not impact YOUR Class or any other classes using your class.

I hope I have been able to make some sense. Do let me know your thoughts/questions and I will try to answer in the comments.

Akhilesh Shukla

Senior Frontend Developer at Pink Triangle Press

5 年

Looking forward to explanation of other SOLID principles as well... And I love your examples! Thank you

Bharti Shukla

Software Engineer| API Development| Backend Development | JavaScript | Java | nodejs | python | Web Development | Spring Boot | Django | AngularJs

5 年

Explained SRP in an easily understandable manner.?

Ankit Chandel

Mobile Apps || Android || React Native || Kotlin || SOLID Principles

6 年

Nice article

Nishi Kant Sharma

Tech Lead - Ruby on Rails (ROR)

6 年

Thank you sir for your detailed description about SRP.

Manisha Yadav

Co-Founder and Director at Zapbuild Technologies

6 年

Really Crisp and Detailed explanation of SRP. A lot of articles miss the core point about cohesion and coupling of classes and generally focus on repeating the definition given by R. Martin. Very well written. Looking forward to the next articles in the series

要查看或添加评论,请登录

Amritpal Singh的更多文章

  • Understanding Time Complexity of Algorithms (Big O)

    Understanding Time Complexity of Algorithms (Big O)

    In Computer Science, the efficiency of any program or algorithm is measured in terms of the Time and Space Complexity…

    2 条评论
  • Are Design Patterns Bad?

    Are Design Patterns Bad?

    If you are a programmer, you must have seen or even participated in the age old argument/discussion/debate of OOP vs…

  • 5 minutes guide to some commonly used Design Patterns

    5 minutes guide to some commonly used Design Patterns

    After a few messages to my LI profile regarding the commonly used Design Patterns, and how to identify the problem, I…

  • SOLID Design Principles - Open Closed Principle (OCP)

    SOLID Design Principles - Open Closed Principle (OCP)

    In the second part of the series, We will have a look at one of the most important principles OCP or Open Closed…

    12 条评论
  • Blockchain (Part 2) - Mining

    Blockchain (Part 2) - Mining

    I have discussed minutely about mining and Proof-of-Work in Part 1 of the article. I'll try to explain the technical…

    10 条评论
  • BlockChain (Part 1) - Introduction

    BlockChain (Part 1) - Introduction

    A lot of my friends and people I know from software and technology background are talking about this pleasantly strange…

    15 条评论
  • Dynamic Programming - Part 2

    Dynamic Programming - Part 2

    In the First part of the article, we saw a simple example of Dynamic Programming and how it can optimize the algorithm…

  • Dynamic Programming - Part 1

    Dynamic Programming - Part 1

    Dynamic Programming is a general algorithm design technique that comes handy to solve certain kind of problems…

    5 条评论
  • Inversion of Control (IoC) and Dependency Injection (DI)

    Inversion of Control (IoC) and Dependency Injection (DI)

    Inversion of Control is a generic design principle of software architecture that assists in creating reusable, modular…

    12 条评论

社区洞察

其他会员也浏览了