개요
프로그래밍을 하면서 자연스럽게 접하게 되는 단어이다보니 Template이란 단어가 무엇인지 굳이 보지 않아도 어떤 틀을 말한다라고 알고 있었다. 정확히는 글자모양으로 구멍이 뚫려있는 판으로, 구멍에 팬을 대고 그으면 모양 그대로 글씨가 써지는 틀을 말하는 것이다. 필기구나 잉크가 무엇으로 사용하든 모양은 그대로 나오게 되는데 이를 프로그래밍적으로 바라보면 Template Method 패턴이 이해가 쉽게 된다.
사용자가 사용하려는 Method는 정해져 있고 기본적인 동작도 정해져 있다. 그런데 그 내부동작이나 세부 요건은 원하는 방식에 따라 달라질 수 있는 것이 Template Method 패턴이다.
아래 예제에서는 AbstractDisplay 클래스의 display()메서드가 Template Method이다. 사용자는 그냥 display() 메서드만 호출하면 정해진 대로 동작하게 된다. 개발자는 AbstractDisplay 클래스를 상속해서 display() 메서드의 실제 동작을 구현하면 실제 코드가 변경이되거나 어떻게 구성되는지와 상관없이 display()메서드의 기본적인 동작은 동일하게 보장이 되는 것이다.
역할
Template Method 패턴의 Role은 아래와 같다.
AbstractClass 역할
템플릿 메소드를 구현해 틀을 정의한다. 템플릿 메소드가 사용할 추상 메소드를 선언한다.
ConcreteClass 역할
AbstractClass를 상속하고 템플릿 메소드가 사용하는 추상 메소드를 구현한다.
Client 역할
사용자는 그저 템플릿 메소드만 호출하면 정해진 틀대로 동작하게 된다.
이득 및 유의사항
템플릿 메소드 패턴을 사용함으로 사용자는 다양한 ConcreteClass의 세부 동작을 이해하지 않아도 큰 틀에서 어떻게 동작하는지 쉽게 파악이 가능하다. 그리고 AbstractClass 매개 변수에 ConcreteClass의 인스턴스가 대입되는데 가능한 LSP(리스코브 치환 원칙)에 따라 매개 변수를 통해 어떤 인스턴스가 오던지 동작이 가능하도록 구현하는 것이 좋다.
예제 코드
//AbstractClass
public abstract class AbstractDisplay {
public abstract void open();
public abstract void print();
public abstract void close();
public final void display() {
open();
for(int i=0; i<5; i++) {
print();
}
close();
}
}
//ConcreteClass1
public class CharDisplay extends AbstractDisplay{
private char ch;
public CharDisplay(char ch) {
this.ch = ch;
}
@Override
public void open() {
// TODO Auto-generated method stub
System.out.print("<<");
}
@Override
public void print() {
// TODO Auto-generated method stub
System.out.print(ch);
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println(">>");
}
}
//ConcreteClass2
public class StringDisplay extends AbstractDisplay{
private String string;
private int width;
public StringDisplay(String string) {
this.string = string;
this.width = string.getBytes().length;
}
@Override
public void open() {
// TODO Auto-generated method stub
printLine();
}
@Override
public void print() {
// TODO Auto-generated method stub
System.out.println("|"+string+"|");
}
@Override
public void close() {
// TODO Auto-generated method stub
printLine();
}
private void printLine() {
System.out.print("+");
for(int i=0; i<width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}
//Client
public class TemplateMethodTester {
public static void main(String[] args) {
// TODO Auto-generated method stub
AbstractDisplay d1 = new CharDisplay('H');
d1.display();
AbstractDisplay d2 = new StringDisplay("hello");
d2.display();
AbstractDisplay d3 = new StringDisplay("안녕하세요");
d3.display();
}
}
'디자인 패턴' 카테고리의 다른 글
5. Singleton 패턴 (0) | 2020.12.02 |
---|---|
4. FactoryMethod 패턴 (0) | 2020.12.01 |
2. Adapter 패턴 (0) | 2020.11.29 |
1. Iterator 패턴 (0) | 2020.11.28 |
0.디자인 패턴이란? (0) | 2020.11.27 |