Design Pattern

21. 템플릿 메서드 패턴 ( template pattern)

킹차니 2022. 1. 1. 20:51

템플릿 메서드 패턴

알고리즘 구조를 서브 클래스가 확장할 수 있도록 템플릿으로 제공하는 방법.

--> 추상 클래스는 템플릿을 제공하고 하위 클래스는 구체적인 알고리즘을 사용한다.

 

알고리즘의 구조(예:1.파일을 읽은 뒤,  2.적절히 파싱한뒤,  3.출력한다.)를 템플릿으로 제공한다. 그리고 각각의 1, 2, 3들 중 달라질 수 있는 부분이 있다면 서브 클래스는 요 달라지는 부분만 직접 구현한다.

AbstractClass의 templateMethod()는 알고리즘의 구조를 표현하는 메소드이다.

 


코드로 알아보기

간단하게 숫자로만 이루어진 txt파일을 읽어서 해당 파일의 숫자들을 모두 덧셈한 결과를 알려주는 기능이 있다고 해보자.

 

numbers.txt 텍스트 파일은 아래와 같고

1
2
3
4
5

 

Client 코드는 아래와 같다.

파일의 Path를 FileProcessor에게 주고, process메서드를 호출하면 연산 결과를 반환해준다.

 

FileProcess

클라이언트를 실행하면 15가 출력될 것이다.

그런데 이때 덧셈이 아닌 모든 숫자들을 곱셈해주는 기능이 필요하다고 하면 아래와 같이 기존의 FileProcessor에서 덧셈을 곱셈으로 바꾼 새로운 클래스를 만들어 주면 된다.

 

MulFileProcess

❗️문제점 ❗️

그런데 위의 MulFileProcessor와 FileProcessor를 보면 "+=" 과 "*="의 부분만 다르고 나머진 똑같은 것을 알 수 있다.

이러한 중복되는 코드를 템플릿 메서드 패턴을 적용하여 없애보자.

 

먼저 FileProcessor 추상 클래스를 만든다. 

요 AbstractClass는 공통되는 로직을 그대로 가지고, 달라지는 부분만 추상 메서드로 분리한다.

이제 각 ConcreteClass들은 이를 상속하여 getResult만 구현하면 되는 것이다. 

먼저 덧셈을 하는 PlusFileProcessor를 보자.

 

곱셈을 하는 MulFileProcessor는 다음과 같다.

 

중복되는 코드들은 AbstractClass에 모아두고 다른 부분만 각 클래스들이 구현하도록 하여 중복이 사라지고 가독성도 좋아졌다.

 

클라이언트를 보면 다음과 같다.

 


 

그런데 위와 같은 템플릿 메소드 패턴과 유사하지만 다른 템플릿 콜백 패턴이 있다.

 

템블릿 콜백 패턴

콜백으로 상속대신 위임을 사용하는 템플릿 패턴

--> 상속 대신 익명 내부 클래스 또는 람다식을 사용할 수 있다.

즉 아래와 같이 Callback인터페이스인 Operator를 만든다.

 

그리고 FileProcessor추상 클래스가 아닌 일반 클래스가 되고, process는 Operator타입을 인자로 받아 Operator의 getResult메서드를 호출하도록 하는 것이다.

이제 Client에서는 아래와 같이 하면 된다.

이는 클래스를 만들지 않고 위임을 사용할 수 있는 좋은 방법이다. (물론 클래스로 Operator를 Implements한 클래스를 사용한 구현도 가능하다.)

 

 


장점과 단점

 

장점

1. 템플릿 코드를 재사용하고 중복 코드를 줄일 수 있다.

2. 템플릿 코드를 변경하지 않고 상속을 받아서 구체적인 알고리즘만 변경할 수 있다.

 

단점

1. 리스코프 치환 법칙을 위반할 여지가 있다. (만약 하위클래스에서 process를 오버라이드하여 재정의 할 수 있다.)

2. 알고리즘 구조가 복잡할 수록 템플릿을 유지하기 어려워진다.

 


실제로 어디에 사용되나?

 

1. 자바의 서블릿

우리가 HttpServlet을 extends하고 doGet또는 doPost메서드를 오버라이드 하면 서블릿이 자신의 로직을 수행하다가 doGet, doPost를 호출해야 할 때, 위의 클래스를 참조하여  doGet, doPost 메서드를 실행한다.( 이때 해당 코드에 대한 제어권은 우리에게 없다. DI )

 

 

2. 스프링의 Configuration

WebSecurityConfigureAdapter를 extends하고 configure메서드를 오버라이드하면 우리가 스프링 Config의 거대한 알고리즘들 중 우리가 일부를 구현하게 되는 것이다.

 

 

출처: 인프런 백기선님 '코딩으로 학습하는 GoF 강의'
https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4