https://www.inflearn.com/courses/lecture?courseId=327901&type=LECTURE&unitId=94427
지금까지 로그 추적기를 잘 만들었다. 그치만 실제로 도입하기에는 아쉬운점이 있음. 핵심 비즈니스 로직에 로그를 위한 코드를 계속 작성해줘야 하기 때문.
@GetMapping("/v3/request")
public String request(String itemId) throws InterruptedException {
TraceStatus status = null;
try {
status = trace.begin("OrderControllerV3.request()");
orderService.orderItem(itemId);
trace.end(status);
return "ok";
} catch (Exception e) {
//로그 때문에 예외를 캐치했지만, 로그는 원래 예외가 터진 코드 흐름에 영향을 주면 안되므로 다시 예외를 던져야 한다.
trace.exception(status, e);
throw e;
}
}
이를 달리 말하면 핵심 로직과 부가 로직이 함께 섞여있다고 할 수 있다.
이 문제를 어떻게 해결할 수 있을까? 잘보면 위의 코드들은 부가기능(로그)를 위한 코드 내부에 핵심기능을 위한 코드가 들어가있다. 즉 부가기능을 위한 코드는 계속 중복됨.
그런데 단순 메서드로 추출하기는 좀 어려운게 중간에 try-catch가 걸려있고, 핵심 코드가 중간에 있어서 단순히 메서드로 추출하는게 어려움.
좋은 설계는 코드의 변하는 부분과 변하지 않는 코드를 분리하는 것이다. 이 둘을 분리해서 모듈화할 수 있다.
여기서 템플릿 메서드 패턴을 사용해보자.
다음과 같은 코드가 있다고 해보자. 반복되는 코드를 확인할 수 있다.
private void logic1() {
long startTime = System.currentTimeMillis();
//비즈니스 로직 실행
log.info("비즈니스 로직1 실행");
//종료
long endTime = System.currentTimeMillis();
long retTime = endTime - startTime;
log.info("resultTime={}", retTime);
}
private void logic2() {
long startTime = System.currentTimeMillis();
//비즈니스 로직 실행
log.info("비즈니스 로직2 실행");
//종료
long endTime = System.currentTimeMillis();
long retTime = endTime - startTime;
log.info("resultTime={}", retTime);
}
딱봐도 비즈니스 로직을 감싸는 로직을 모듈화하고 싶어진다.