Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

Template Method - 적용1 본문

인프런/[인프런] 스프링 핵심 원리 - 고급

Template Method - 적용1

Seung__ 2021. 11. 22. 19:46

1.  AbstractTemplate Class


  • AbstractTemplate 은 템플릿 메서드 패턴에서 부모 클래스이고, 템플릿 역할을 한다.
  • <T> 제네릭을 사용했다. 반환 타입을 정의한다.
  • 객체를 생성할 때 내부에서 사용할 LogTrace trace 를 전달 받는다.
  • 로그에 출력할 message 를 외부에서 파라미터로 전달받는다.
  • 템플릿 코드 중간에 call() 메서드를 통해서 변하는 부분을 처리한다.
  • abstract T call() 은 변하는 부분을 처리하는 메서드이다. 이 부분은 상속으로 구현해야 한다.
public abstract class AbstractTemplate<T> {

    private final LogTrace trace;

    public AbstractTemplate(LogTrace trace) {
        this.trace = trace;
    }

    public T execute(String message){
        TraceStatus status = null;

        try{
            status = trace.begin(message);

            //로직 호출, 변하는 부분
            T result = call();

            trace.end(status);
            return result;

        }catch (Exception e){
            trace.exception(status, e);
            throw e;
        }
    }

    protected abstract T call();
}

 

 

2. Controller V4


  • AbstractTemplate<String>
    • 제네릭을 String 으로 설정했다. 따라서 AbstractTemplate 의 반환 타입은 String 이 된다.
  • 익명 내부 클래스
    • 익명 내부 클래스를 사용한다.
    •  객체를 생성하면서 AbstractTemplate 를 상속받은 자식 클래스를 정의.
    • 따라서 별도의 자식 클래스를 직접 만들지 않아도 된다.
  • template.execute("OrderController.request()")
    • 템플릿을 실행하면서 로그로 남길 message 를 전달한다.
@RestController //@Controller +@ResponseBody
@RequiredArgsConstructor
public class OrderControllerV4 {

    private final OrderServiceV4 orderService;
    private final LogTrace trace;

    @GetMapping("/v4/request")
    public String request(String itemId){

        AbstractTemplate<String> template = new AbstractTemplate<String>(trace) {
            @Override
            protected String call() {
                orderService.orderItem(itemId);
                return "ok";
            }
        };

        return template.execute("OrderController.request()");
    }
}

 

 

 

3. Service V4


  • AbstractTemplate<Void>
  • 제네릭에서 반환 타입이 필요한데, 반환할 내용이 없으면 Void 타입을 사용하고 null 을 반환
  • 참고로 제네릭은 기본 타입인 void , int 등을 선언할 수 없다.
  • 기존 v3에서 반환 void
@Service
@RequiredArgsConstructor
public class OrderServiceV4 {

    private final OrderRepositoryV4 orderRepository;
    private final LogTrace trace;

    public void orderItem(String itemId){
        
        AbstractTemplate<Void> template = new AbstractTemplate<>(trace) {
            @Override
            protected Void call() {
                orderRepository.save(itemId);
                return null;
            }
        };

        template.execute("OrderService.orderItem()");
    }
}

 

 

 

4. RepositoryV4


@Repository
@RequiredArgsConstructor
public class OrderRepositoryV4 {

    private final LogTrace trace;

    public void save(String itemId){

        AbstractTemplate<String> template = new AbstractTemplate<String>(trace) {
            @Override
            protected String call() {
                if (itemId.equals("ex")){
                    throw new IllegalStateException("예외 발생");
                }
                sleep(1000);
                return "ok";
            }
        };

        template.execute("OrderRepository.save()");

    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

 

 

5. 결과



[2b3fc8f7] OrderController.request()
[2b3fc8f7] |-->OrderService.orderItem()
[2b3fc8f7] |  |-->OrderRepository.save()
[2b3fc8f7] |  |<--OrderRepository.save() time=1015ms
[2b3fc8f7] |<--OrderService.orderItem() time=1016ms
[2b3fc8f7] OrderController.request() time=1017ms

 

 

6. GitHub : 211122 TemplateMethod1


 

GitHub - bsh6463/Spring_Advanced: initial

initial. Contribute to bsh6463/Spring_Advanced development by creating an account on GitHub.

github.com

 

Comments