추상 클래스가 있고 이를 상속하여 구체적으로 구현하는 하위클래스가 있습니다. 하위클래스 들이 어떻게 구현되는지에 따라 프로그램이 다르게 실행 될 것입니다. 하지만 템플릿 패턴은 상위 클래스에서 큰 흐름을 제공해주고 하위 클래스에 구체적인 내용을 결정하는 디자인 패턴을 템플릿 패턴이라고 합니다.
요약
추상클래스를 통해 프로그램 큰 흐름을 제공해주고 이를 상속하는 클래스들이 구체적으로 구현하는 패턴입니다.
Java
//추상 클래스
public abstract class AbstractPrint {
public abstract void open ();
public abstract void print ();
public abstract void close ();
public void write () {
open ();
for (int i = 0 ; i < 5 ; i++ )
print ();
close ();
}
}
// StringDisplay
public class StringDisplay extends AbstractPrint {
String name ;
int width ;
public StringDisplay (String name ) {
this .name = name;
this .width = name .length ();
}
public void open () {
this .printLine ();
}
public void print () {
System .out .println ("|" + this .name + "|" );
}
public void close () {
this .printLine ();
}
public void printLine () {
StringBuilder line = new StringBuilder ();
line .append ("*" );
for (int i = 0 ; i < this .width ; i++ )
line .append ("-" );
line .append ("*" );
System .out .println (line);
}
}
// CharDisplay
public class CharDisplay extends AbstractPrint {
char chararcter ;
int width ;
public CharDisplay (char chararcter ) {
this .chararcter = chararcter;
}
public void open () {
System .out .print ("<<" );
}
public void print () {
System .out .print (this .chararcter );
}
public void close () {
System .out .println (">>" );
}
}
// Main
public class Main {
public static void main (String [] args ) {
AbstractPrint hello = new StringDisplay ("Hi Hoony's Blog" );
AbstractPrint patternName = new StringDisplay ("Hi Template Pattern" );
AbstractPrint c = new CharDisplay ('c' );
hello .write ();
c .write ();
patternName .write ();
}
}
// 출력
추상 클래스를 charDisplay와 StringDisplay들이 상속 받아서 구현하고 있다.
추상 클래스의 method write를 보면 구현되어 있지 않는 메소드들이 호출되고 있다.
이런 점을 보아 두 클래스는 같은 흐름을 갖고 있더라도 상속 받은 클래스가 메소드를 어떻게 구현해주는가에 따라 프로그램 결과가 달라집니다.
Java Python
//Abstract Class
import abcclass AbstractPrint: __metaclass__ = abc.ABCMeta @abc.abstractmethod def open (self ): pass @abc.abstractmethod def print_input (self ): pass @abc.abstractmethod def close (self ): pass def display (self ): self .open() for i in range (0 , 5 ): self .print_input()
self.close()
// Concrete Class
from AbstractPrint import AbstractPrintclass StringDisplay(AbstractPrint): def __init__ (self , input_string): self .output_string = input_string self .width = len (input_string) def open (self ): self .printLine() def print_input (self ): print ("|" + self .output_string + "|" ) def close (self ): self .printLine() def printLine (self ): result += "+" for i in range (0 , self .width): result += "-" result += "+" print (result, end =" \n " )if __name__ == "__main__" : hi = StringDisplay("hi" ) hi.display()
Python 만약 템플릿 패턴을 구현하지 않고 복사, 붙여넣기를 통해 구현한다면 class1, class2, class3 등등이 만들어 질 것이다. 그럼 oop의 특성상 클래스를 추상화하여 숨기지 못하고 하나의 클래스에서 버그가 발생하면 나머지 클래스도 손을 봐야할 것이다.
그러므로 이 패턴은 크게는 공통된 로직으로 작동하며 세부적인 내용이 바뀔 때 사용하면 좋을 것이다.