[디자인패턴] 템플릿 메서드 패턴(Template Method Pattern)이란? 템플릿 메서드 예시

템플릿 메서드 패턴이란?

템플릿 메서드 패턴은 소프트웨어 공학에서 동작 상 알고리즘의 프로그램 뼈대를 정의하는 행위 디자인 패턴이다.
-위키백과-

템플릿 메서드
[그림 1] 템플릿 메서드

 

템플릿 메서드 패턴은 알고리즘의 골격을 부모 클래스에서 정의하되, 자식 클래스들이 해당 알고리즘의 구조를 변경하지 않고 알고리즘의 특정 단계들을 오버라이드(재정의) 할 수 있도록 하는 행동 디자인 패턴이다.

 

템플릿 메서드 패턴은 부모 클래스에서 알고리즘을 일련의 단계들(메서드)로 나누고 단일 템플릿 메서드 내부에서 이러한 메서드들을 호출한다. 자식 클래스는 단일 템플릿 메서드 내부에서 호출되는 메서드들 중에서 필요한 경우 선택적으로 오버라이드 하여 사용할 수 있다.

 

이렇게 하면 중복을 제거하고 다형성을 확보할 수 있다.

 

 

템플릿 메서드 예시

예를 들어 쉽게 이해해 보자.

 

라면을 끓이는 과정 중 특정 토핑을 추가해 떡라면, 치즈라면, 김치라면을 끓인다고 하자.

 

셋 모두 비슷한 과정을 거칠 것이다.

 

1. 물을 끓인다

2. 스프를 넣는다( ※ 나는 라면을 끓일 때 항상 스프 먼저 넣는다)

3. 면을 넣는다.

4. 토핑을 넣는다. <-- 이 부분만 라면을 끓이는 과정에서 다름

 

이걸 코드로 나타내면 다음과 같다.

 

public class DduckRamyun{
	...
	public void boilWater() {
		System.out.println("물을 끓입니다.");
	}
	
	public void putSoup() {
		System.out.println("스프를 넣습니다.");
	}
	
	public void putMyun() {
		System.out.println("면을 넣습니다.");
	}
	
	public void putTopping() {
		System.out.println("떡을 넣습니다");
	}
    ...
}

public class CheeseRamyun{
	...
	public void boilWater() {
		System.out.println("물을 끓입니다.");
	}
	
	public void putSoup() {
		System.out.println("스프를 넣습니다.");
	}
	
	public void putMyun() {
		System.out.println("면을 넣습니다.");
	}
	
	public void putTopping() {
		System.out.println("치즈를 넣습니다");
	}
    ...
}

public class KimchiRamyun{
	...
	public void boilWater() {
		System.out.println("물을 끓입니다.");
	}
	
	public void putSoup() {
		System.out.println("스프를 넣습니다.");
	}
	
	public void putMyun() {
		System.out.println("면을 넣습니다.");
	}
	
	public void putTopping() {
		System.out.println("김치를 넣습니다");
	}
    ...
}

 

putTopping() 메서드를 제외하고는 모든 과정이 동일하다.

 

이러한 경우 템플릿 메서드 패턴을 적용해 중복을 제거할 수 있다.

 

abstract class Ramyun{
	public void cook() {
		boilWater();
		putSoup();
		putMyun();
		putTopping();
	}
	
	public void boilWater() {
		System.out.println("물을 끓입니다.");
	}
	
	public void putSoup() {
		System.out.println("스프를 넣습니다.");
	}
	
	public void putMyun() {
		System.out.println("면을 넣습니다.");
	}
	
	public abstract void putTopping();
	
}

public class DduckRamyun extends Ramyun{
	
	@Override
	public void putTopping() {
		System.out.println("떡을 넣습니다");
	}
}

public class CheeseRamyun extends Ramyun {
	
	@Override
	public void putTopping() {
		System.out.println("치즈를 넣습니다");
	}
}

public class KimchiRamyun extends Ramyun{
	
	@Override
	public void putTopping() {
		System.out.println("김치를 넣습니다");
	}
}

 

떡라면, 치즈라면, 김치라면의 부모 클래스인 abstract class Ramyun을 만들고,

라면을 끓이는 단계들을 모은 cook() 템플릿 메서드를 만든다.

 

cook() 템플릿 메서드에는 라면을 끓이는 단계들(메서드들)이 모여있다.

여기서 토핑을 넣는 메서드인 putTopping() 만 자식 클래스에서 오버라이딩 해주면 되는 것이다.

 

 

템플릿 메서드 예시
[그림 2] 예시

 

클래스 다이어그램으로 나타내면 위와 같다.

 

 

템플릿 메서드 패턴 장단점

장점

  • 중복코드를 제거할 수 있다.
  • 알고리즘의 특정 부분만 오버라이드하도록 하여 다른 부분에 발생하는 변경에 영향을 덜 줄 수 있다

단점

  • 알고리즘의 제공된 골격에 의해 제한될 수 있다.
  • 리스코프 치환 원칙을 위반 할 수 있다. 
  • 단계가 많을 수록 복잡해져 유지가 어려워지는 경향이 있다.

 

참고) 리스코프 치환 원칙을 모른다면? 

[프로그래밍 언어론] 객체 지향 설계 5원칙 (SOLID)란?

 

 

정리

템플릿 메서드 패턴은 사실 객체 지향 프로그래머라면 의도하지 않고 구현하는 경우가 많을 것이다. 모든 디자인 패턴이 그렇듯 외울 필요 없이 응용할 수만 있다면 되는 것이다.

 

템플릿 메서드 패턴은 특정 클래스들에서 중복이 발생하지만 약간의 차이가 있는 경우 사용하면 중복을 제거할 수 있다.

 

 


참고

 

1.https://ko.wikipedia.org/wiki/%ED%85%9C%ED%94%8C%EB%A6%BF_%EB%A9%94%EC%86%8C%EB%93%9C_%ED%8C%A8%ED%84%B4

2. https://refactoring.guru/ko/design-patterns/template-method

 

반응형

댓글

Designed by JB FACTORY