클린코드(Clean Code)란?
: 읽기 쉽고 이해하기 쉬운 좋은 코드를 작성하는 것으로 코드 자체가 가독성이 뛰어나고 유지 보수가 쉽도록 작성되어야 한다.
클린코드는 품질 높은 코드 작성을 위한 원칙이다. 그러나 원칙을 엄격하게 따르다보면 문제들이 생길 수 있다.
클린코드 한계
1. 초기 개발 속도 저하
가독성과 유지보수성을 높이기 위해 코드를 반복적으로 설계하고 리팩토링해야 한다. 이 과정에서는 명확한 변수명과 클래스 구조를 만들어야 하며, 이러한 추가 작업으로 인해 속도가 늦춰질 수 있다.
2. 복잡성 증가
복잡성 증가 원인
- 지나치게 클린코드를 적용하여 간단한 로직에도 과도한 추상화가 발생하여 코드 복잡성 증가
- 클린코드를 작성할때는 다양한 디자인 패턴을 적용하라고 권장함, 하지만 모든 상황에 디자인 패턴을 적용하게 될 경우 코드가 복잡해지며, 불필요한 구조가 추가 될 수 있음
- 클린 코드 원칙을 무리하게 적용하여 코드 복잡성 증가
=> 성능 저하의 원인이 되기도 한다.
// EmailService 인터페이스
class EmailService {
sendEmail(recipient, subject, body) {
throw new Error("Method 'sendEmail' must be implemented.");
}
}
// SmtpEmailService 클래스
class SmtpEmailService extends EmailService {
sendEmail(recipient, subject, body) {
// SMTP 프로토콜을 사용한 이메일 발송 로직
console.log(`Sending email to ${recipient} with subject: "${subject}"`);
// 실제 SMTP 전송 로직을 여기에 구현
}
}
// EmailController 클래스
class EmailController {
constructor(emailService) {
this.emailService = emailService;
}
send(recipient, subject, body) {
this.emailService.sendEmail(recipient, subject, body);
}
}
// 사용 예시
const smtpService = new SmtpEmailService();
const emailController = new EmailController(smtpService);
emailController.send("example@example.com", "Test Subject", "This is the body of the email.");
-> 단순한 이메일 전송 기능을 여러 추상화 계층을 도입하여 클래스 간의 복잡성 증가
방안
리팩토링을 통해 복잡성을 줄일 수 있다. (코드 가족성 높이고, 유지보수에 도움)
리팩토링?
프로그램의 외부 동작은 그대로 둔 채, 내부의 코드를 정리하면서 개선하는 것
// 수정 전
public int getFoodPrice(int arg1, int arg2){
return arg1 * arg2;
}
// 수정 후
public int getTotalFoodPrice(int price, int quality){
return price * quality;
}
// 수정 전 - price * quantity가 중복
public int getTotalPrice(int price, int quantity, double discount){
return (int) ((price * quantity)) * (price * quantity) * (discount/100));
}
// 수정 후 - private으로 함수 하나를 더 만들어 사용
public int getTotalPrice(int price, int quantity, double discount){
int totalPriceQuantity = price * quantity;
return (int) ((totalQuantity - getDiscountPrice(discount, totalPriceQuantity))
}
private double getDiscountPrice(double discount, int totalPriceQuantity){
return totalPriceQuantity * (discount/100);
}
리팩토링 방법
- 메소드 추출(Extract Method)
- 클래스 추출(Extract Class)
- 메소드 인라인(Inline Method)
- 조건문 간소화(Simplify Conditional)
- 루프를 파이프라인으로 변환(Convert Loops to Pipeline)