SOLID is an acronym that represents five fundamental principles of object-oriented programming, proposed by Robert C. Martin - Uncle Bob. Here you can read more about his article.
These principles aim to improve the structure and maintenance of code, making it more flexible, scalable and easier to understand.
These principles help the programmer to create more organized codes, dividing responsibilities, reducing dependencies, simplifying the refactoring process and promoting code reuse.
The "S" in the acronym stands for "Single Responsibility Principle". The phrase that uncle bob used to define this principle was:
"A class must have one, and only one, reason to change."
According to this principle, when we develop our classes, we need to keep their particular functionality in mind. If a class deals with two functionalities the best thing to do is to split it.
When learning object-oriented programming, it is common to assign multiple responsibilities to a single class, creating so-called God Classes. Although this approach initially seems efficient, it mixes responsibilities, making it difficult to change one without impacting the others.
To exemplify a practical application of this problem, I will create a class called UserService. It will handle various needs related to users.
First, let's look at the application of this class without using the Single Responsibility Principle. Here our class does several things: manipulates user data, validates this data, and creates users in the database.
import java.util.ArrayList; import java.util.List; class User { private int id; private String name; private String email; public User(int id, String name, String email) { this.id = id; this.name = name; this.email = email; } @Override public String toString() { return "User{id=" id ", name='" name "', email='" email "'}"; } } class UserService { private Listusers = new ArrayList(); public void addUser(String name, String email) { if (this.validateEmail(email)) { User newUser = new User(users.size() 1, name, email); users.add(newUser); saveToDatabase(newUser); } else { throw new IllegalArgumentException("E-mail inválido"); } } private boolean validateEmail(String email) { return email.matches("\\S @\\S \\.\\S "); } private void saveToDatabase(User user) { System.out.println("Salvando usuário no banco de dados " user); } public List getUsers() { return users; } public static void main(String[] args) { UserService userService = new UserService(); userService.addUser("John Doe", "[email protected]"); System.out.println(userService.getUsers()); } }
type User = { id: number, name: string, email: string } class UserService { private users: User[] = []; addUser(name: string, email: string) { if (this.validateEmail(email)) { const newUser = { id: this.users.length 1, name: name, email: email }; this.users.push(newUser); this.saveToDatabase(newUser); } else { throw new Error("E-mail inválido"); } } private validateEmail(email: string): boolean { const emailRegex = /\S @\S \.\S /; return emailRegex.test(email); } private saveToDatabase(user: User) { console.log("Salvando usuário no banco de dados", user); } getUsers() { return this.users; } }
The main problem we can find here is code maintenance. If there is a change in the validation logic or the way data is saved, it will directly affect this class, making it difficult to maintain.
Now, how can we solve this?
We must segregate our logic contained in the God Class "UserService" into several classes with well-defined functionalities. Let's see:
import java.util.ArrayList; import java.util.List; // validador class EmailValidator { public boolean validate(String email) { return email.matches("\\S @\\S \\.\\S "); } } // Repositório que manipula os dados no banco de dados class UserRepository { private Listusers = new ArrayList(); public void save(User user) { System.out.println("Salvando usuário no banco de dados " user); users.add(user); } public List getAll() { return users; } } // Aplicamos as regras do domain com injeção de dependências class UserService { private EmailValidator emailValidator; private UserRepository userRepository; public UserService(EmailValidator emailValidator, UserRepository userRepository) { this.emailValidator = emailValidator; this.userRepository = userRepository; } public void addUser(String name, String email) { if (emailValidator.validate(email)) { User newUser = new User(userRepository.getAll().size() 1, name, email); userRepository.save(newUser); } else { throw new IllegalArgumentException("E-mail inválido"); } } public List getUsers() { return userRepository.getAll(); } }
// validador class EmailValidator { validate(email: string): boolean { const emailRegex = /\S @\S \.\S /; return emailRegex.test(email); } } // Repositório que manipula os dados no banco de dados class UserRepository { private users: { id: number, name: string, email: string }[] = []; save(user: { id: number, name: string, email: string }) { console.log("Salvando usuário no banco de dados", user); this.users.push(user); } getAll() { return this.users; } } // Aplicamos as regras do domain com injeção de dependências class UserService { constructor( private emailValidator: EmailValidator, private userRepository: UserRepository ) {} addUser(name: string, email: string) { if (this.emailValidator.validate(email)) { const newUser = { id: this.userRepository.getAll().length 1, name: name, email: email }; this.userRepository.save(newUser); } else { throw new Error("E-mail inválido"); } } getUsers() { return this.userRepository.getAll(); } }
Applying the Single Responsibility Principle is crucial for creating robust and scalable software. By ensuring that each class has only one responsibility, we reduce code complexity, facilitate maintenance and refactoring, and minimize the risk of errors. This principle is fundamental to maintaining the quality and longevity of the project, promoting a cleaner and more efficient design.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3