[디자인 패턴] Template Callback Pattern

벼랑 끝 코딩·2025년 3월 21일

Design Pattern

목록 보기
5/6

반복적인 작업을 차단하고 효율적으로 작업을 수행하기 위해서
변하지 않는 부분과 변하는 부분을 분리해내는 디자인 패턴으로는
상속을 사용하는 Template Method Pattern
구현을 사용하는 Strategy Pattern이 있다.

알고리즘 골격(변하지 않는 부분)을 정의하고
일부 단계(변하는 부분)를 하위 클래스로 연기하는 두 패턴은
일부 단계를 재정의하기 위해 매번 클래스를 생성해야 한다는 단점이 있었지만,
익명 클래스를 사용하여 단점을 일부 극복했다.

Template Method Pattern에서 발생하는 상속의 단점은
Strategy Pattern의 구현을 통해 극복했다.

Template Callback Pattern은 두 패턴과 같은 목적이지만
Strategy Pattern에서 형태만 조금 달라진 패턴이다.
어떻게 달라졌는지 한번 살펴보자.

Strategy Pattern

interface Strategy {  // 전략 인터페이스
	void method();
}

class Strategy1 implements Strategy {  // 전략 1구현 
	@Override
    public void method() {
    	// 메서드 바디
    }
}

class Strategy2 implements Strategy {  // 전략 2 구현
	@Override
    public void method() {
    	// 메서드 바디
    }
}

class Service {
    
    public void serviceMethod() {
    
    	// ** 전략 1이 필요한 경우 Strategy1 사용 **
    	Strategy strategy = new Strategy1(); 
        
        // ** 전략 2가 필요한 경우 Strategy2 사용 **
    	Strategy strategy = new Strategy2();
        
        
    	strategy.method();
    }
}

Strategy Pattern은 변하는 부분을 인터페이스로 선언하고,
전략들을 하나씩 구현해서 각 상황에 맞게 필요한 전략을 사용하는 방식이다.

전략을 사용하기 위해 Strategy Pattern에서는 내부에서 객체를 생성했다.
변하는 부분에서 전략을 사용하여 반복적인 작업을 차단하면서도,
전체 알고리즘을 쉽게 교체할 수 있는 유용한 디자인 패턴이었다.

Template Callback Pattern

Template Callback Pattern을 단어 그대로 사용해 풀어 설명하면,
변하지 않는 부분을 정의한 알고리즘 골격(Template)에
변하는 부분을 호출(Call)한 시점의 뒤(Back)에 실행된다고 해서 템플릿 콜백 패턴이다.

Strategy Pattern은 변하는 부분을 내부에 객체를 생성하여 전달했다면,
Template Callback Pattern은 변하는 부분을 람다로 전달한다는 부분이 다른데
전달할 때 호출, 즉 람다를 사용하여 메서드만을 전달해서 이러한 이름이 붙었다.

class Service {
    
    public void serviceMethod(Strategy strategy) {  // ** 파라미터로 전달 **

    	strategy.method();
    }
}

전략 패턴에서 내부 객체를 생성했던 코드가 없어지고
메서드를 호출할 때 람다로 전달하는 부분이 달라졌다.

public void clientMethod() {
	Service service = new Service();
    
    //  ** 전략에 따라 다른 파라미터 람다 전달 **
	service.serviceMethod(() -> {
    	method1();
    });
    
    service.serviceMethod(() -> {
    	method2()
    });
}

전략을 람다로 전달하면, 실행 시점에 Client가 전략을 변경할 수 있기 때문에
더욱 유연하게 서비스를 운영할 수 있다.
템플릿 콜백 패턴의 경우에도 람다로 전달하여 클래스를 별도로 생성하지 않고
더욱 간단하게 전략을 사용할 수 있게 됐다.

단점

public void clientMethod() {
	Service service = new Service();
    
    //  ** 전략에 따라 다른 파라미터 람다 전달 **
	service.serviceMethod(() -> {
    	method1(() -> {
        	innerMethod(() -> {
            	innerInnerMethod();
            });
        });
    });
}

템플릿 콜백 패턴은 람다를 파라미터로 전달하기 때문에 가독성이 떨어진다.
안그래도 가독성 측면에서 문제가 발생하는데,
메서드 내부에서도, 내부의 내부에서도 템플릿 콜백 패턴을 사용한다면
이게 몇번이나 중첩된다면 아마 코드 가독성 퀄리티는 바닥을 칠 것이다.

이렇게 템플릿 콜백 패턴이 중첩되는 현상을 콜백 헬(Callback Hell)이라고 부른다.

마무리

실행 중에 더욱 유연하게 전략을 사용한다는 점에서
당연히 Template Callback Pattern이 우수해보이지만,
프로젝트 규모에 따라 명확성이 필요한 경우 전략 패턴을 고려해야 한다.

반복되는 코드 작성을 줄일 수 있고
유연하게 객체를 변경하여 사용할 수 있는 디자인 패턴의 사용을 고려해보자.

profile
복습에 대한 비판과 지적을 부탁드립니다

0개의 댓글