본문 바로가기
개발자 일지/Java

[디자인패턴]템플릿 메소드 패턴(Template Method Pattern)

by 네빌링 2021. 3. 3.
반응형

-디자인패턴 중 템플릿 메소드 패턴을 알아본다.


템플릿 메소드 패턴이란?

 

다른 디자인패턴에 비해 비교적 간단한 패턴 같다.  참고한 YABOONG님 블로그에 소개된 GOF 정의를 소개하자면,

 

Defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure.

 

라고 정의되어 있다.

 

슈퍼클래스의 한 메소드에 알고리즘 뼈대를 정의하고 서브클래스에 몇단계들을 맡긴다. 템플릿 메소드(뼈대를 정의한 메소드)는 서브클래스가 알고리즘 구조 변경없이 알고리즘의 특정 단계들을 알아서 정의하도록 냅둔다.

 

정도로 해석할 수 있다.

 

즉, 슈퍼클래스에는 로직의 뼈대와 그 뼈대를 사용하는 템플릿 메소드를 만들고, 서브클래스에서는 그 로직의 뼈대를 원하는대로 구현하여 사용하는 패턴이다.

 

간단하게 예제를 구현하며 학습해본다.

 

템플릿 메소드 패턴 예제

 

슈퍼클래스에 햄버거를 만드는 알고리즘 뼈대와 이 알고리즘을 수행할 템플릿 메소드를 만들고, 그 뼈대를 상속받은 서브클래스들에서 각각 다른 종류의 버거를 만든다.

 

package TemplateMethod;

public abstract class MakingBurger {
	public abstract void bakingBread();	//알고리즘의 뼈대
	public abstract void makingMeat();	//알고리즘의 뼈대
	public abstract void cheese();		//알고리즘의 뼈대
	
	public void makingBuger() {	//템플릿 메소드
		bakingBread();
		makingMeat();
		cheese();
	}
}

 

위와 같이 알고리즘의 뼈대만 추상 메소드로 만들고, 실제로 수행할 템플릿 메소드는 알고리즘뼈대만 호출한다. 이 템플릿 메소드는 바뀌지 않는다.

 

package TemplateMethod;

public class DoubleCheeseBurger extends MakingBurger {
	@Override
	public void bakingBread() {
		System.out.println("브리오슈번 굽기");	//서브클래스에서 알고리즘 구현
	}
	
	@Override
	public void makingMeat() {
		System.out.println("패티2개 굽기");	//서브클래스에서 알고리즘 구현
	}
	
	@Override
	public void cheese() {
		System.out.println("체다치즈 2장");	//서브클래스에서 알고리즘 구현
	}
}

 

package TemplateMethod;

public class VeganBurger extends MakingBurger{
	@Override
	public void bakingBread() {
		System.out.println("유기농밀 번 굽기");	//서브클래스에서 알고리즘 구현
	}
	@Override
	public void makingMeat() {
		System.out.println("콩으로만든 패티");	//서브클래스에서 알고리즘 구현
	}
	@Override
	public void cheese() {
		System.out.println("치즈 없음");	//서브클래스에서 알고리즘 구현
	}

}

 

DoubleCheeseBurger와 VeganBurger는 알고리즘 뼈대 메소드를 오버라이딩하여 각각 다른 방식으로 구현한다.

 

package TemplateMethod;

public class Cooking {
	public static void main(String[] args) {
		MakingBurger cheeseBurger = new DoubleCheeseBurger();
		MakingBurger veganBurger  = new VeganBurger();
		
		//템플릿 메소드 실행
		cheeseBurger.makingBuger();	
		System.out.println("------");
		veganBurger.makingBuger();
	}
}

//실행결과

//브리오슈번 굽기
//패티2개 굽기
//체다치즈 2장
//------
//유기농밀 번 굽기
//콩으로만든 패티
//치즈 없음

 

위와 같이 같은 템플릿 메소드를 실행하여 다른 결과를 도출한다.

 

템플릿 메소드 패턴은 토비의 스프링 3.1에서 소개가 잘 되어있다. 1장 오브젝트와 의존관계 챕터에서 add()와 get() 메서드가 템플릿 메소드이고 여기서 사용하는 connection관련 알고리즘을 다른 클래스에서 정의해서 사용하는 예시로 나와있으니 참고하면 도움이 될 것이다.

 

자바에서 사용되는 템플릿 메소드 패턴

 

AbstractMap<K,V>클래스를 상속받은 HashMap, TreeMap 클래스가 대표적이다.

AbstractMap<K,V>는 Map 인터페이스를 구현한다.

여기서 get() 메소드를 구현한다. 여기서 HashMap, TreeMap이 AbstractMap<K,V>를 상속하여 get()을 각각의 방식대로 다시 구현한다.

템플릿 메소드 패턴이 적용된 것을 볼 수 있다.

 

잘 보면 그냥 추상클래스의 메소드를 상속받아 구현하는 걸 어렵게 말한 것 같다.

아니면 내가 모르는 좀 더 심오한 무언가가 있을수도 있겠지만 좀 더 학습해보면 확실해질 것 같다.

이 부분에 대해 자세한 내용은 출처에 더 디테일하게 설명되어 있으니 참고하면 좋겠다.

 

 

출처 : yaboong.github.io/design-pattern/2018/09/27/template-method-pattern/

 

반응형