클래스는 객체 지향 프로그래밍에서 매우 중요하지만 제대로 설계되지 않은 클래스는 문제가 있는 코드로 이어질 수 있습니다.
클린 코드 10장은 단일 책임을 지닌 응집력 있는 클래스의 중요성을 강조합니다.
이 글에서는 주요 통찰력을 공유하고 JavaScript에서의 적용을 시연해 보겠습니다.
응집력은 클래스의 책임이 얼마나 밀접하게 관련되어 있는지를 나타냅니다.
결속력 있는 수업은 단일 목적에 초점을 맞추고 자연스럽게 서로 어울리는 책임을 갖습니다.
이렇게 하면 클래스가 단순하고, 읽기 쉽고, 유지 관리하기 쉽습니다.
예: 낮은 응집력
class User { constructor(name, email) { this.name = name; this.email = email; } // Handles user registration register() { // Registration logic } // Sends email to user sendEmail(message) { // Email sending logic } // Logs activity of the user logActivity(activity) { console.log(`${this.name} performed: ${activity}`); } }
위의 예에서 User 클래스에는 사용자 등록, 이메일 보내기, 활동 로깅이라는 세 가지 관련 없는 책임이 있습니다.
이 클래스는 동시에 너무 많은 일을 하려고 하기 때문에 응집력이 부족합니다.
단일 책임 원칙에 따르면 클래스에는 변경 이유가 단 하나만 있어야 합니다. 이는 각 수업이 하나의 관심사에 집중해야 함을 의미합니다.
클래스에 둘 이상의 책임이 있는 경우 한 영역이 변경되면 다른 영역의 기능이 중단될 수 있습니다.
SRP를 준수하도록 위의 예를 리팩토링해 보겠습니다.
class User { constructor(name, email) { this.name = name; this.email = email; } } class UserRegistrationService { register(user) { // Registration logic } } class EmailService { sendEmail(user, message) { // Email sending logic } } class ActivityLogger { logActivity(user, activity) { console.log(`${user.name} performed: ${activity}`); } }
이제 각 클래스에는 단일 책임이 있습니다.
이 구조를 사용하면 이메일 시스템을 변경해도 사용자 등록 논리에 영향을 주지 않으며 그 반대도 마찬가지입니다.
유지관리성: 클래스에 단일 책임이 있으면 버그를 찾고 수정하기가 더 쉽습니다. 관련 없는 논리를 헤쳐나갈 필요가 없습니다.
확장성: 프로젝트가 성장함에 따라 SRP를 준수하면 새 기능을 추가하는 것이 더 간단해집니다. 기존 클래스를 건드리지 않고도 새 클래스에 새로운 기능을 추가할 수 있습니다.
테스트 가능성: 단일 책임이 있는 클래스는 테스트하기가 더 쉽습니다. 각 클래스에는 범위가 제한되어 있으므로 단위 테스트는 개별 기능 부분에 집중할 수 있습니다.
수업이 응집력 있게 진행되도록 하려면 여러 책임이 결합되는 영역을 찾으세요.
종종 수업은 간단하게 시작되지만 기능이 추가됨에 따라 추가 업무가 쌓일 수 있습니다.
예: 결제 시스템 리팩토링
여러 작업을 처리하는 PaymentProcessor 클래스가 있다고 가정해 보겠습니다.
class PaymentProcessor { constructor() { this.paymentGateway = new PaymentGateway(); } processPayment(paymentDetails) { // Payment processing logic } validatePaymentDetails(paymentDetails) { // Validation logic } logTransaction(paymentDetails) { console.log(`Payment processed: ${JSON.stringify(paymentDetails)}`); } }
여기서 PaymentProcessor는 결제 처리, 세부 정보 확인 및 거래 로깅을 담당합니다.
이는 책임을 리팩터링하고 분할할 수 있는 기회입니다.
class PaymentProcessor { constructor(paymentGateway, validator, logger) { this.paymentGateway = paymentGateway; this.validator = validator; this.logger = logger; } processPayment(paymentDetails) { if (this.validator.isValid(paymentDetails)) { this.paymentGateway.process(paymentDetails); this.logger.logTransaction(paymentDetails); } } } class PaymentValidator { isValid(paymentDetails) { // Validation logic return true; // Simplified for example } } class PaymentLogger { logTransaction(paymentDetails) { console.log(`Payment processed: ${JSON.stringify(paymentDetails)}`); } }
이제 PaymentProcessor 클래스에는 결제 처리라는 단일 책임이 있습니다.
검증 및 로깅이 별도의 클래스(PaymentValidator 및 PaymentLogger)로 이동되었습니다.
단일 책임 원칙을 준수하고 응집력 있게 클래스를 설계하면 코드베이스가 유연하고 유지 관리 가능하며 이해하기 쉽습니다.
책임을 별도의 집중적인 클래스로 나누면 개별 구성 요소의 복잡성이 줄어들고 시스템이 더욱 강력해집니다.
클래스가 대규모 프레임워크나 애플리케이션에서 자주 사용되는 JavaScript에서는 이러한 원칙을 따르면 코드 품질이 크게 향상됩니다.
클린 코드(Clean Code) 책에서 설명하듯이, 클린 클래스를 작성하는 것은 단지 코드를 정리하는 것이 아니라 유지 관리가 악몽이 되지 않으면서도 발전할 수 있는 시스템을 만드는 것입니다.
즐거운 코딩하세요!
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3