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 |