CleanCode

Clean Code 짜기2

김대근'IT공부 2019. 10. 21. 20:12

함수 당 추상화 수준은 하나로
한 함수 내에 추상화 수준을 섞으면 코드 해석에 많은 어려움이 생긴다.

추상화 수준이 높음 -    getHtml()

추상화 수준이 적당함 - String pagePathName = PathParser.render(pagepath);
추상화 수준이 낮음 -    append("\n")

코드는 위에서 아래로 한 함수 다음 추상화 수준은 한 단계 낮은 함수가 오도록 한다.

( TO 문단을 읽듯이 프로그램이 읽혀야 함) - 내려가기 규칙


추상화 함수의 핵심 - 짧으면서도 '한 가지'만 하는 함수
------------------------------------------
직원 유형에 따라 다른 값 계산해 반환하는 함수
public Money calculatePay(Employee e) 
      throws InvaIidEmployeeType { 
           switch (e.type) { 
                case COMMISSIONED: 
                      return calculateCommissionedPay(e); 
                case HOURLY: 
                      return calculateHourlyPay(e); 
                case SALARIED: 
                      return calculateSalariedPay(e); 
                default:
                      throw new InvalidEmployeeType(e.type);
            }
}
------------------------------------------
위 함수의 문제점


1. 새 직원 유형을 추가하면 함수의 길이가 더 길어진다.


2. 한 가지 작업만 수행하지 않는다.


3. 객체 지향 설계 방식 SRP를 위반한다. 

( Single responsibility principle 단일 책임 원칙 : 한 클래스는 하나의 책이만 가져야 한다.)

 

4. 객체 지향 설계 방식 OCP를 위반한다.

(Open/closed principle 개방-폐쇄 원칙 : 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.)

 

5. 위 함수와 동일한 구조의 함수가 무한정 존재한다.
ex) isPayday(Employee e, Date date); 
   deliverPay(Employee e, Money pay);

해결 - switch 문을 추상 팩토리에 숨긴다.
switch 문을 사용해 Employee 파생 클래스의 인스턴스를 생성하고, 함수는 Employee 인터페이스를 거쳐 호출이 된다.
-> 다형성으로 인해 실제 파생 클래스의 함수가 실행된다.

------------------------------------------
public abstract class Employee { 
public abstract boolean isPayday(); 
public abstract Money calculatePay(); 
public abstract void deliverPay(Money pay);


public interface EmployeeFactory { 
public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;

 

public class EmployeeFactoryImpl implements EmployeeFactory { 
public Employee makeEmployee(EmployeeReco rd r) throws InvalidEmployeeType { 
 

 switch (r.type) { 
   case COMMISSIONED:
       return new CommissionedEmployee(r) ; 


   case HOURLY:
       return new HourlyEmployee(r); 


   case SALARIED:
       return new SalariedEmployee(r); 


   default:
       throw new InvalidEmployeeType(r.type);
                    }
          }
}
------------------------------------------

참고한 책

클린 코드 (Clean Code)

반응형