Understanding SOLID in C++?: Single Responsibility Principle
Most of the time, We write code which satisfies the current requirements, but our main goal should be to write code in such a way that it is easy to maintain, easy to understand, easy to evolve as per future requirements. Along with that we need to avoid duplication in our code and reduce the complexity that can exists in our code.
There is a popular way in which you can write the code which will help you to achieve the above mentioned points.
S.O.L.I.D -> SOLID is a acronym which stands for a set of principles which can help you to write code which follows the above goals.
The reason for creating this article is that despite lot of resources and videos there are on SOLID Design Principles, we rarely find anything that uses C++ implementation for explaining these principles. SOLID does not depend on language, nor anything changes in C++ for implementing these design principles but it is always good to have examples that you can directly relate for understanding SOLID in C++. C++ developer will agree with me.?
In this article, we will understand about first principle of SOLID which is Single Responsibility Principle using examples in C++.
Single Responsibility Principle
It states that class should have only one reason to change. In simple words, it means a class should do only one Job.
Lets understand this with an example
class User
public:
void login() {
cout << "User logged in" << endl;
}
void logout() {
cout << "User logged out" << endl;
}
void printUserInfo(string username) {
cout << "Username: " << username << endl;
}
};{
In the above example “User” if you see it has multiple responsibilities i.e authentication (login and logout) and printing the information of the user.
For the above class, there can be two reasons for which implementation of class can change which is change in authentication or change in printing the user information.
We can see that both the logic are independent to each other. We can move these two responsibilities into two different classes which will contain the logic of Authentication and printing user information.
class Authentication
public:
void login() {
cout << "User logged in" << endl;
}
void logout() {
cout << "User logged out" << endl;
}
};
class UserInfo {
public:
void printUserInfo(string username) {
cout << "Username: " << username << endl;
}
};
class User : public Authentication, public UserInfo {
};
int main() {
User user;
user.login();
user.printUserInfo("Abhishek");
user.logout();
return 0;
}{
By separating these responsibilities into different classes( Authentication, UserInfo) we follow the Single Responsibility Principle, which will make the code easier to read, maintain, and modify.?
We can inherit these classes into our User class which will perform all the operations. Now if we need to change the Authentication Logic for the User, we just need to change the Authentication class.
领英推荐
Lets take an another example for our understanding.
FileManager?
We have a requirement to write some text to the file and read text from the file. Think loud, how will you implement this in consideration to Single Responsibility Principle.
Let say we ignore SRP and implement the above, we can have a class FileManager which can have method saveToFile() and readFromFile()
class FileManager
public:
void saveToFile(string filename, string data) {
ofstream file(filename);
file << data;
file.close();
}
vector<string> readFromFile(string filename) {
vector<string> data;
string line;
ifstream file(filename);
while (getline(file, line)) {
data.push_back(line);
}
file.close();
return data;
}
};
Now the above class has two responsibilities, Can we think of making a class that will only have one responsibility?
We can have two classes FileWriter and FileReader, which each have a single responsibility.
class FileWriter
public:
void saveToFile(string filename, string data) {
ofstream file(filename);
file << data;
file.close();
}
};
class FileReader {
public:
vector<string> readFromFile(string filename) {
vector<string> data;
string line;
ifstream file(filename);
while (getline(file, line)) {
data.push_back(line);
}
file.close();
return data;
}
};
class FileManager : public FileReader, public FileWriter {
};
int main() {
FileManager file_manager;
file_manager.saveToFile("data.txt", "Hello, World!");
vector<string> data = file_manager.readFromFile("data.txt");
for (string line : data) {
cout << line << endl;
}
return 0;
}{
We can use inheritance to make our FileManager class to inherit these functionality from these classes.
I hope we have understand the first principle of SOLID i.e. Single Responsibility Principle using the examples in C++.?
We will go through the remaining principles in our next article. Hope you learned somethings through this. See you in next article.?
Subscribe to my newsletter for upcoming articles. I am targeting to cover low level design topics with case studies and the implementation and examples will be in C++.
Happy Coding!?
TIP: Implement these principles in C++ with some examples, its very easy to understand the applications.
Senior software engineer at Gene S Pty Ltd
1 年Abhishek Anand That was a great explanation. Can you please suggest some good references to learn more about SOLID principles in C++?
Software Engineer 2 - INTUIT | Ex - NOKIA | Gold Medalist - NIT Agartala 21'??| ReactJs, Javascript, Typescript, Redux, GraphQL, Java, Kotlin, Springboot, Frontend, Backend, DSA, System Design, HLD, LLD, Design Patterns
1 年Valuable ??
Building Smarter Solutions with Data || Solving Complex Problems with Data || Passionate About Building AI-Powered Solutions || Bridging Data and Intelligence
1 年Thanks for valuable content.
Competitive Programmer || 3?? @CodeChef || Android Developer || 350 Problem (GFG& Leetcode)
1 年It's Good