본문 바로가기
Spring

[스프링 핵심 원리 - 고급편] 5. 템플릿 콜백 패턴

by doogfoot 2024. 1. 7.

[스프링 핵심 원리 - 고급편] 5. 템플릿 콜백 패턴

 

템플릿 콜백 패턴

 

 

템플릿 콜백 패턴 - 정의

 

템플릿 콜백 패턴은 이전 포스팅에서 설명드린 전략 패턴의 변형된 형태, 혹은 확장된 형태의 패턴입니다.

전략 패턴의 기본적인 구조에 변경되는 코드 부분(전략, 동작)을 매번 클래스로 만들지 않고 익명 내부 클래스로 사용하는 패턴을 말합니다

 

패턴의 이름이 템플릿 콜백인데 여기서 전략 패턴의 변하지 않는 로직인 컨텍스트가 템플릿 역할을 하고 변경되는 로직인 전략이 콜백으로 넘어오기 때문에 붙여진 이름입니다.

 

전략 패턴에서 템플릿 콜백 패턴으로 용어를 변경하면 다음과 같습니다.

  • Strategy Pattern → Template Callback Pattern
  • Context → Template
  • Strategy → Callback

 

프로그래밍 분야에서 콜백이란 다른 코드의 인수로써 넘겨주는 실행 가능한 코드를 콜백이라고 합니다. 콜백을 넘겨 받는 코드는 이 콜백 로직을 필요에 따라 즉시 실행할 수도 있고, 나중에 실행할 수도 있습니다.

 

 

템플릿 콜백 패턴 - 예제

 

템플릿 콜백 패턴 예제는 전략 패턴의 예제를 조금 수정해서 설명하겠습니다.

// 콜백 인터페이스
public interface PaymentCallback {
    void pay();
}

 

기존 전략 패턴은 위의 인터페이스를 각각의 전략별로 구현체를 만들어서 사용했지만 템플릿 콜백 패턴은 인터페이스만 만들어서 사용합니다.

 

// 템플릿
public class PaymentTemplate {
    
    // 수행 메서드
    public void performPayment(PaymentCallback callback) {
        if (callback != null) {
            callback.pay();
        } else {
            System.out.println("No payment strategy set.");
        }
    }
}

 

템플릿 클래스를 만들고 공통적인 로직을 작성합니다. 그리고 변경되는 로직을 callback이라는 이름의 파라미터로 입력받아서 실행하게 되어있습니다.

 

PaymentTemplate paymentTemplate = new PaymentTemplate();

// 신용 카드 결제 로직 callback 으로 넘김
paymentTemplate.performPayment(new PaymentCallback() {
    @Override
    public void pay() {
    	System.out.println("Credit Card Payment"); 
    }
});

// 페이팔 결제 로직 callback 으로 넘김
paymentTemplate.performPayment(new PaymentCallback() {
    @Override
    public void pay() {
    	System.out.println("PayPal Payment"); 
    }
});

 

위의 코드는 클라이언트에서 어떤 방식으로 결제를 수행할지를 결정하는 로직입니다.

 

템플릿 코드의 결제 수행 함수(perfromPayment)를 호출하면서 익명 내부 클래스를 통해 callback 함수를 인자로 넘기고 있습니다.

 

이렇게 템플릿 콜백 패턴을 사용하면 perfromPayment 의 공통된 로직을 수행하다가 중간에 변경되는 일부 로직을 callback으로 넘겨서 실행할 수 있습니다.

 

 

PaymentTemplate paymentTemplate = new PaymentTemplate();

// 신용 카드 결제 로직 callback 으로 넘김
paymentTemplate.performPayment(() -> System.out.println("Credit Card Payment"));

// 페이팔 결제 로직 callback 으로 넘김
paymentTemplate.performPayment(() -> System.out.println("PayPal Payment"));

 

참고로 콜백을 넘길 때 익명 클래스를 사용하지 않고 Java8 부터 도입된 람다식(Lambda)을 사용하여 위의 코드와 같이 표현할 수도 있습니다

 

 

 

위의 코드는 실제 스프링에서 사용중인 JdbcTemplate이라는 클래스의 코드 일부입니다.

 

JdbcTemplate 은 템플릿 콜백 패턴을 사용하여 쿼리를 수행하기 위한 공통된 로직은 템플릿화 하고 변경되는 쿼리 부분만 Callback으로 넘겨서 실행하는 예제라고 할 수 있습니다.

 

 

템플릿 콜백 패턴 - 장점

 

템플릿 콜백 패턴은 전략 패턴과 비슷하기 때문에 공통 로직과 변경되는 로직을 분리할 수 있는 효과가 있습니다

 

추가적으로 전략 별로 클래스를 따로 만들지 않기 때문에 사용하기 간편하다는 점도 장점이 될 수 있습니다.

 

템플릿 콜백 패턴 - 정리

 

템플릿 콜백 패턴은 결국 전략 패턴과 익명 내부 클래스(혹은 람다식)를 결합한 패턴입니다

 

공통적으로 변하지 않는 로직을 템플릿으로 만들고 변경되는 부분만 콜백으로 넘겨서 유연하게 변경할 수 있는 방법입니다.

 

앞에서 포스팅 했던 템플릿 메서드 패턴, 전략 패턴을 포함하여 이번에 템플릿 콜백 패턴은 사용 의도가 비슷한 것 같습니다

 

변경되지 않는 로직과 매번 변경되는 로직을 분리합니다. 그리고 변경되는 로직을 추상 클래스 혹은 인터페이스로 정의하여 유연하게 변경할 수 있도록 도와주는 패턴들입니다.

 

그중 사용이 편하고 장점이 좀 더 있는 템플릿 콜백 패턴을 일반적으로 많이 사용할 것 같고 개발할 때 유용하게 사용할 것 같습니다.

 

댓글