'템플릿 메서드 패턴'과 '전략 패턴'의 사용시기

특정 로직에 대해서 ‘템플릿 메서드 패턴’을 사용할 수도 있고, ‘전략 패턴’을 사용할 수도 있다. 다형성을 활용하는 방법이 다를 뿐이고, 우리가 이루려는 목적은 동일하게 이룰 수 있다. 그렇다면 언제 ‘템플릿 메서드 패턴’을 쓰는 것이 좋고, 언제 ‘전략 패턴’을 쓰는 것이 좋은 것인지 알아보자.

사용 시기

런타임 때 로직을 변경해야 하는 경우 - 전략 패턴

전략 패턴은 컨텍스트 클래스가 전략(Strategy)을 속성(필드, 인스턴스 변수)으로 가지고 있다보니, setter 메서드를 통해 런타임 도중에 전략(Strategy)을 변경할 수 있다.

하지만 템플릿 메서드 패턴은 로직을 변경하려면 클래스로부터 인스턴스를 새로 생성해야 한다. 따라서 런타임 도중에 로직을 변경할 수가 없다.

컨텍스트 클래스가 상속을 받은 클래스인 경우 - 전략 패턴

템플릿 메서드 패턴이 기본적으로 ‘상속’을 활용한 구조이다. 그러다보니 원래 컨텍스트 클래스가 상속을 받고 있는 클래스라면, 템플릿 메서드 패턴을 사용하는 순간 상속의 깊이가 1단계에서 2단계가 된다. 상속 구조가 깊어지면 유지보수가 힘들어 진다.

반면 전략 패턴은 ‘상속 구조’를 사용하는 구조가 아니므로, 상속 구조가 더 깊어지지 않는다.

다양한 컨텍스트 클래스에서 전략(Strategy)을 공유하고 싶을 때 - 전략 패턴

정렬 알고리즘, Predicates, Compare 등과 같은 것들은 여러 컨텍스트 클래스에서 사용하는 경우가 종종 있다. 이 때에는 ‘전략 패턴’을 사용하면 된다.

왜냐하면 템플릿 메서드 패턴은 로직의 순서가 고정되어 있어서, 고정된 로직 순서와 일치하는 컨텍스트 클래스에서 밖에 사용을 못한다.

하지만 전략 패턴에서는 전략(Strategy)이 아예 클래스로 분리가 되어 있어서, 로직의 순서와 상관없이 전략(Strategy)에서 필요한 메서드들을 마구잡이로 배치해서 사용해도 상관없다.

위 경우를 제외한 상황 - 템플릿 메서드 패턴

템플릿 메서드 패턴이 ‘상속’과 ‘추상 클래스’를 사용해서 구현하다보니, 사람이 생각하기에 가장 직관적으로 코드를 구현할 수 있게 된다. 또한 전략 패턴에서 사용하는 객체를 주입해서 로직을 완성시켜야 하는 ‘의존성 주입(DI)’에 대한 코드를 작성하지 않아도 되서, 훨씬 간단하게 구현할 수 있다.

References

When to use template method Vs. Strategy?

상속의 단점과 Strategy Pattern