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가 걸려있고, 핵심 코드가 중간에 있어서 단순히 메서드로 추출하는게 어려움.

좋은 설계는 코드의 변하는 부분과 변하지 않는 코드를 분리하는 것이다. 이 둘을 분리해서 모듈화할 수 있다.

여기서 템플릿 메서드 패턴을 사용해보자.

템플릿 메서드 패턴 - 예제 1

다음과 같은 코드가 있다고 해보자. 반복되는 코드를 확인할 수 있다.

    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);
    }

딱봐도 비즈니스 로직을 감싸는 로직을 모듈화하고 싶어진다.