SOLID는 Robert C. Martin(Bob 삼촌)이 제안한 객체 지향 프로그래밍의 5가지 기본 원칙을 나타내는 약어입니다. 여기에서 그의 기사에 대한 자세한 내용을 읽을 수 있습니다.
이러한 원칙은 코드의 구조와 유지 관리를 개선하여 코드를 더욱 유연하고 확장 가능하며 이해하기 쉽게 만드는 것을 목표로 합니다.
이러한 원칙은 프로그래머가 보다 체계적인 코드를 작성하고, 책임을 나누고, 종속성을 줄이고, 리팩토링 프로세스를 단순화하고, 코드 재사용을 촉진하는 데 도움이 됩니다.
약어의 "S"는 "단일 책임 원칙"을 의미합니다. Bob 삼촌이 이 원칙을 정의하기 위해 사용한 문구는 다음과 같습니다.
"수업에는 변경 이유가 하나만 있어야 합니다."
이 원칙에 따라 클래스를 개발할 때 클래스의 특정 기능을 염두에 두어야 합니다. 클래스가 두 가지 기능을 다루는 경우 가장 좋은 방법은 클래스를 분할하는 것입니다.
객체 지향 프로그래밍을 배울 때 단일 클래스에 여러 책임을 할당하여 소위 God 클래스를 만드는 것이 일반적입니다. 이 접근 방식은 처음에는 효율적인 것처럼 보이지만 책임이 혼합되어 다른 책임에 영향을 주지 않고 하나를 변경하기가 어렵습니다.
이 문제의 실제 적용 사례를 보여주기 위해 UserService라는 클래스를 만들겠습니다. 사용자와 관련된 다양한 요구를 처리합니다.
먼저 단일 책임 원칙을 사용하지 않고 이 클래스를 적용하는 방법을 살펴보겠습니다. 여기서 우리 클래스는 사용자 데이터를 조작하고, 이 데이터의 유효성을 검사하고, 데이터베이스에 사용자를 생성하는 등 여러 가지 작업을 수행합니다.
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; } }
여기서 찾을 수 있는 주요 문제는 코드 유지 관리입니다. 검증 로직이나 데이터 저장 방식이 변경되면 이 클래스에 직접적인 영향을 미쳐 유지 관리가 어려워집니다.
이제 어떻게 해결할 수 있을까요?
God 클래스 "UserService"에 포함된 로직을 잘 정의된 기능을 갖춘 여러 클래스로 분리해야 합니다. 보자:
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(); } }
단일 책임 원칙을 적용하는 것은 강력하고 확장 가능한 소프트웨어를 만드는 데 중요합니다. 각 클래스에 하나의 책임만 부여함으로써 코드 복잡성을 줄이고 유지 관리 및 리팩토링을 촉진하며 오류 위험을 최소화합니다. 이 원칙은 프로젝트의 품질과 수명을 유지하고 보다 깨끗하고 효율적인 설계를 촉진하는 데 기본입니다.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3