탬플릿 패턴

반응형
반응형

탬플릿? 

 

뭔가 느낌이 일정한 모형 틀을 만들어 놓고,

그 틀을 계속 사용하는 느낌이다.

 

구글에서 템플릿 관련 이미지를 찾았다.

 죄다 ppt관련 이미지 밖에 없었다. 왜 ppt를 만들때 템플릿을 사용할까?

가장 뻔한 이유로는 편하기 때문이다. 

어차피 제목 이나 내용빼고는 이미 구현되었기 때문에 우리는 제목과 내용만 추가하면 된다. 물론 내가 발표할 주제와   ppt의 상관관계는 지켜야 하겠지만...

 

근데... 디자인 패턴에서는 템플릿을 어떻게 사용할까?

사실 이름에는 메소드라는 단어가 숨겨져 있다. 메소드가 있는 이유는 이 패턴은 메소드의 역할이 크기 때문이다.

 

예를들어 A라는 클래스와 B라는 클래스를 만든다고 가정하자.

근데 A와 B클래스는 공통적으로 사용되는 메소드가 있다.

이 메소드를 한곳에 넣어주면 된다.

public void method() {

   a();
   b();
   c();

}

바로 이런식으로 말이다. 물론 이것만 해도 충분히 훌륭한 템플릿이다. 하지만 위의 ppt처럼 제목이나 내용을 사용자 마음대로 추가할 수 는 없다. 왜냐하면 그런 기능이 전혀 없기 때문이다. 지금 이건 이대로 하라고 강제로 하는거 와 다름없다.

그럼에도 이게 템플릿인 이유는 이것만 사용해 주면 되기 때문이다. 

 

근데 d메서드나, e메서드는 클래스마다 변한다고 가정해보자.

그러면 위처럼 만들기는 힘들다. 더욱이 순서까지 강제했기 때문에 더 이상 확장은 불가능해 보인다.

 

그래서 


public abstract class Template {

public void method() {
	a();
    b();
    c();
}

public void a() {
	생략
}

public void b() {
	생략
}

public void c() {
	생략
}

abstract void d();
abstract void e();

}

이런식으로 작성했다. 그랬더니 d와 e메소드는 이것을 구현한 구현체에서 구현만 해주면 된다.

(물론, d와e도 메서드에 넣어도 되고, a,b,c가 메서드에 있어야 하는 것은 아닙니다.)

 

근데 이럴 수 도 있다. c라는 메서드는 특정 값에 따라 사용할 수도 있고 없을 수 도 있다.

이럴때 사용되는것이 바로 후크다.

디자인 패턴 책을 보면 후크는 기본적인 내용만 구현되어있고, 아무 코드도 들어있지 않는 코드라는 뜻이다.라고 나와 있습니다. 여기서 기본적인것이라는 뜻은 String이라면 ""혹은 null이 int 라면 0-999 가 , boolean 이라면 true혹은 false를 말합니다. 그러니까 return값을 뜻합니다. 리턴이 없으면 그 메소드는 사용할 수 없기 때문이죠.

 

public abstract class Template {

public void method() {
	a();
    b();
    
    if (isCan()) {
    c();
    }
    d();
    e();
}

public void a() {
	생략
}

public void b() {
	생략
}

public void c() {
	생략
}

boolean isCan() {
  return true;
}

abstract void d();
abstract void e();

}

이 메서드를 어떻게 구현함에 따라 true이면 c메서드가 호출이 될것이며, false이면 호출되지 않을 것입니다.

 

자 이제 이것에 맞는  예제를 가져오겠습니다. 이것또한 예제를 만들기 귀찮아서 a,b,c로 대체 했는데 이게 또 이해가 안갈 수 있죠.(아 또 바꼈네.ㅎㅎ)

 

바로 커피와 차를 만드는 클래스입니다.

public abstract class CaffeineBeverageWithHook {
	final void prepareRecie() {
		boilWater();
		brew();
		pourInCup();
		if (customerWantsCondiments()) {
		addCondiments();
		}
	}

	

	abstract void brew();

	abstract void addCondiments();

	void boilWater() {
		System.out.println("물을 끓이는 중");
	}

	void pourInCup() {
		System.out.println("컵에 따르는 중");
	}
	
	boolean customerWantsCondiments() {
		return true;
	}

}

간단히 설명하면

커피나 차를 만드는데... 순서가 있죠... 그것을 강제한 모습이 맨위 메서드입니다. 저는 final을 붙이지 않았는데

이것을 붙이는 이유는 이 순서를 강제할 수 있습니다. 왜냐하면 변하면 안되기 때문이죠.

물을 끓이고, 거르고, 컵에 따르고, 추가적으로 뭔가를 추가하고...

근데 거르는 부분은 차와 커피가 다를 수 있고,

뭔가를 추가하는부분은 이것을 추가할지 않할지 결정할 수 있기 때문에 생략하였습니다.

public class CoffeeWithHook extends CaffeineBeverageWithHook {

	@Override
	void brew() {
		System.out.println("필터를 통해서 커피를 우려내는 중");
	}

	@Override
	void addCondiments() {
		System.out.println("설탕과 우유를 추가하는 중");

	}
	
	@Override
	boolean customerWantsCondiments() {
		String answer = getUserInput();
		
		if (answer.toLowerCase().startsWith("y")) {
			return true;
		}
		
		return false;
	}

	private String getUserInput() {
		String answer = null;
		
		System.out.println("커피에 우유를 넣어 드릴까요? (y/n)  ");
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		try {
			answer = br.readLine();
		}catch (IOException e) {
			System.out.println("IO 오류");
		}
		
		if (answer == null) {
			return "n";
		}
		return answer;
	}
	
	
}

간단히 커피클래스만 호출하였습니다.

 

보니 customerWantsCondiments가 후크 메소드인데...

이런식으로 구현이 되어있군요.

y라면 true이고 아니라면 false이니 추가되지 않겠죠. 설탕이..

 

지금 보면 CaffeineBeverageWithHook 클래스가 알아서 모든것을 결정하죠?

이런것을 보고 할리우드 원칙이라고 합니다. 이렇게 보면 의존성 뒤집기 원칙과 굉장히 유사해서 햇갈리는데...

솔직히 같아 보이긴 합니다.

코드로 보면 다른것 같기도 하고... 아무튼 할리우드 패턴의 뜻은

먼저 연락하지 마세요. 우리가 연락할게요.라는 뜻이라고 한다.

그러니까 CaffeineBeverageWithHook라는 클래스가 서브 클래스들보고 먼저 연락하지 말라는것 같네요.

 

템플릿 패턴은 프레임워크를 만들때 굉장히 많이 사용되는 패턴 중 하나라고 합니다. (스프링에서도 봤어요. dispatherServlet 공부할때...)

그러니 학습하고 있으면 언젠가는 사용날이 오겠죠?

 

 

반응형

'디자인패턴' 카테고리의 다른 글

팩토리 메소드 패턴 vs 추상 팩토리 패턴  (0) 2021.11.11
싱글톤 패턴  (0) 2021.11.03
빌더 패턴  (0) 2020.05.27
프록시 패턴  (0) 2020.05.18
싱글톤 패턴  (0) 2020.05.12

댓글

Designed by JB FACTORY