이 포스팅은 최범균님의 유튜브 영상을 보고 정리한 글입니다.
위의 코드에서는 다양한 조건으로 뭔가를 계산하고, 그 결과를 반영한다.
즉, 계산과 반영 코드가 섞여있다.
계산과 반영 코드를 분리해줘야한다.
입력값
)출력값
)
시각적으로 나타내보면 입력과 출력이 무엇인지 알아내는데 도움이 된다.
// 1. 메소드를 하나 만들고, if절이나 다른 용도로 사용됐던 모든 필요한 값들을 메소드 파라미터로 전달하는 방식
ServicePeriod period = calculatePeriod(order.getGubun(), order.getPayType(), ..., loginDate);
// 2. 메소드를 만들고, order라는 객체를 통으로 주는 방식
ServicePeriod period = calculatePeriod(order, loginDate);
// 3. 같은 클래스의 메소드로 하지 않고, 별도의 객체로 분리해서 객체를 통해 계산하는 방식
ServicePeriod period = new ServicePeriodCalculator(order, loginDate).calculate();
// ServicePeriod
LocalDate sdate = period.getSdate();
LocalDate edate = period.getEdate();
여기서는 3번째 방식을 선택했다.
그 이유는, 객체를 따로 분리해야 로직을 테스트하기 쉽기 때문이다.
ServicePeriod를 만들고, ServicePeriod는 출력값 (edate, sdate)를 갖도록 하자.
public class ServicePeriodCalculator {
private Order order;
private LocalDate loginDate;
public ServicePeriodCalculator(Order order, LocalDate loginDate) {
this.order = order;
this.loginDate = loginDate;
}
public Main calculate() {
LocalDate edate = null;
LocalDate currDate = order.getDate();
LocalDate nextDate = YearMonth.from(currDate.plusMonths(1)).atDay(1);
if (order.getGubun().equals("AA")) {
if (order.getPayType().equals("A") ||
(order.getPayType().equals("W") && order.getIncludePay().equals("1"))) {
if (order.getPayMonth().equals("T")) {
edate = YearMonth.from(currDate).atEndOfMonth();
} else if (order.getPayMonth().equals("N")) {
edate = YearMonth.from(currDate).plusMonths(1).atEndOfMonth();
}
return new ServicePeriod(currDate, edate);
} else if (order.getPayType().equals("W") && order.getIncludePay().equals("2")) {
// ... 생략
}
} else {
if (order.getUnit().equals("D")) {
edate = loginDate.plusDays(order.getQty());
} else if (order.getUnit().equals("M")) {
edate = loginDate.plusMonths(order.getQty());
}
return new ServicePeriod(loginDate, edate);
}
}
}
public class Main {
public void provideServicePeriod(Long ordNo, LocalDate loginDate) {
// period, order 구하고 검사하는 코드 생략
ServicePeriod period = new ServicePeriodCalculator(order, loginDate).calculate();
updatePeriod(period, period.getSdate(), period.getEdate());
}
}