Rlog

Switch 문 반복을 없애기 본문

Java

Switch 문 반복을 없애기

dev_roach 2021. 10. 7. 21:20
728x90

Switch 문을 어떻게 걷어낼 수 있을까? 이건 참 어려운 경우라고 생각한다.

하지만 Switch 의 경우에는 해당 Type 을 걷어내지 않는 이상 불가능하기에 숨기는 형태로 진행할 수 있다고 생각한다.

 

예를 들면 아래와 같은 코드를 보자

public class PayRoll {

    private static final String COMISSIONED = "COMISSIONED";
    private static final String HOURLY = "HOURLY";
    private static final String SALARIED = "SALARIED";

    public Money calculatePay(Employee e) {
        switch(e.type) {
            case COMISSIONED:
                return calculateComissionedPay(e);
            case HOURLY:
                return calculateHourlyPay(e);
            case SALARIED:
                return calculateSalariedPay(e);
        }
    }    
}

위와 같은 코드는 한가지 문제가 있다.

 

첫번째로, 한가지 책임을 지고 있지 않다. 현재 함수를 보면 무언가 지급해주는 것을 계산해 주는 것만 같지만, 현재 역할은 두가지이다.

매개변수로 들어온 Employee 객체의 type 에 따라 어떤 계산식을 시킬지 정하는것, 그리고 해당 계산식을 호출하고 값을 리턴해주는 것.

 

두번째로, 만약 calculateCommisionPay 의 매개변수가 바뀌거나, 혹은 새롭게 추가되는 함수들이 다른 매개변수로 들어와야 한다면 계속해서 해당 함수도 수정이 일어나야 한다. 따라서 확장성도 낮고, 수정할시 사이드 이펙트가 계속해서 발생할 수 있는 코드이다.

 

또한 제일 큰 문제는 결국 저 커미션을 받는 직원에 대한 지급 계산과 이런것들이 함수로서 존재해야하나? 라는 의문점도 있다.

왜냐하면 그럼 커미션을 받는 직원의 지급일을 계산하는 함수인 isPayDay(Employee e, Date date) 를 만든다고 할때도, 계속 swtich 문이나 if/else 문을 추가해야 할 것 이다. 

 

따라서 해당 부분을 타입에 따라 맞는 직원의 객체를 만드는 Factory Method 로 변경해보자.

public abstract class Employee {
    public abstract Money calculatePay();
}
public class ComissionedEmployee extends Employee {

    private EmployeeRecord employeeRecord;

    public ComissionedEmployee(EmployeeRecord employeeRecord) {
        this.employeeRecord = employeeRecord;
    }

    public Money calculatePay() {
        return new Money(100);
    }

}

대략적으로 위와 같은 방식으로 직원들을 하나씩 만들어주자.

 

public interface EmployeeFactory {
    public Employee makeEmployee(EmployeeRecord r)
}
public class EmployeeFactoryImpl implements EmployeeFactory {

    public Employee makeEmployee(EmployeeRecord r) {
        switch(e.type) {
            case COMISSIONED:
                return ComissionedEmployee(e);
            case HOURLY:
                return HourlyEmployee(e);
            case SALARIED:
                return SalaryEmployee(e);
        }
    }

}

위와 같이 하게되면 아까의 함수가 하나의 책임을 다하는 직원 객체를 만드는 형태로 변경되었다.

이로써 하나의 책임을 지는 메소드로 변경될 수 있게 되었고, 계산하는 함수마져 객체 내부에 캡슐화를 시켰기 때문에 객체 안을 봐야만, 어떻게 계산하는지를 알 수 있다. 따라서 객체 내부 프로세스에 외부에서 직접적으로 의존성을 지니지 않게된다.

다형성을 통해서 calculatePay() 메소드를 통해서 직원마다 계산할 수 있도록 할 수 있게 되었다.

'Java' 카테고리의 다른 글

젠킨스 JVM 메모리 설정  (0) 2021.10.20
객체는 무엇일까?  (0) 2021.10.14
JVM 구조  (0) 2021.10.07
[M1] Apache Jmeter로 Socket Server Test 하기  (0) 2021.09.24
[Spring Boot] Jenkins 로 자동 배포하기  (0) 2021.09.21