728x90
출처 : 책 - java 언어로 배우는 디자인 패턴 입문
3. Template Method - 하위 클래스에서 구체적으로 처리하기
1. 목적
- 메소드의 뼈대를 미리 만들어 두기 위해서 사용한다.
> 우리가 흔히 아는 Interface와 class 관계와 비슷한 내용이다.
- 장점 : 인터페이스를 선언하고 구현 하위 클래스 인스턴스를 대입해 사용 할 수 있다.
( 상위 클래스형의 변수에 하위 클래스의 종류를 특정하지 않아도 프로그램이 동작할 수 있도록 한다.
: The Liskov Substitution Principle(LSP) 원칙 )
- 메소들간의 로직을 추상클래스 측에서 작성해, 공통적으로 적용할 수 있다.
2. 예제
(1) 추상 클래스
public abstract class AbstractDisplay { // 추상 클래스 AbstractDisplay
public abstract void open(); // 하위 클래스에 구현을 맡기는 추상 메소드 (1) open
public abstract void print(); // 하위 클래스에 구현을 맡기는 추상 메소드 (2) print
public abstract void close(); // 하위 클래스에 구현을 맡기는 추상 메소드 (3) close
public final void display() { // 추상 클래스에서 구현되고 있는 메소드 display
open(); // 우선 open하고…
for (int i = 0; i < 5; i++) { // 5번 print을 반복하고…
print();
}
close(); // … 마지막으로 close한다. 이것이 display 메소드에서 구현되고 있는 내용.
}
}
(1) 구현 클래스1
public class CharDisplay extends AbstractDisplay { // CharDisplay는 AbstractDisplay의
// 하위 클래스.
private char ch; // 표시해야 할 문자
public CharDisplay(char ch) { // 생성자에서 전달된 문자 ch을
this.ch = ch; // 필드에 기억해 둔다.
}
public void open() { // 상위 클래스에서는 추상 메소드였다.
// 여기에서 오버라이드해서 구현.
System.out.print(“<<”); // 개시 문자열“<<”을 표시한다.
}
public void print() { // print 메소드도 여기에서 구현한다.
// 이것이 display에서 반복해서 호출된다.
System.out.print(ch); // 필드에 기억해 둔 문자를 1개 표시한다.
}
public void close() { // close 메소드도 여기에서 구현.
System.out.println(“>>”); // 종료 문자열 “>>”을 표시.
}
}
(2) 구현 클래스2
public class StringDisplay extends AbstractDisplay { // StringDisplay도
// AbstrctDisplay의 하위 클래스.
private String string; // 표시해야 할 문자열.
private int width; // 바이트 단위로 계산한 문자열의 「폭」.
public StringDisplay(String string) { // 생성자에서 전달된 문자열 string을
this.string = string; // 필드에 기억.
this.width = string.getBytes().length; // 그리고 바이트 단위의 폭도 필드에
// 기억해 두고 나중에 사용한다.
}
public void open() { // 오버라이드해서 정의한 open 메소드.
printLine(); // 이 클래스의 메소드 printLine에서
// 선을 그리고 있다.
}
public void print() { // print 메소드는
System.out.println(“|” + string + “|”); // 필드에 기억해 둔 문자열의
// 전후에 “|”을 붙여서 표시.
}
public void close() { // close 메소드는
printLine(); // open 처럼 printLine 메소드에서
// 선을 그리고 있다.
}
private void printLine() { // open과 close에서 호출된 printLine 메소드이다.
// private이기 때문에 이 클래스 안에서만 사용된다.
System.out.print(「+「); // 테두리의 모서리를 표현하는”+” 마크를 표시.
for (int i = 0; i < width; i++) { // width개의 “-“을 표시하고
System.out.print(「-「); // 테두리 선으로 이용한다.
}
System.out.println(「+「); // 테두리의 모서리를 표현하는 “+” 마크를 표시.
}
}
(3) Main
public class Main {
public static void main(String[] args) {
// 'H'을 가진 CharDisplay 인스턴스를 1개 만든다>
AbstractDisplay d1 = new CharDisplay('H');
// “Hello, world.”을 가진 StringDisplay의 인스턴스를 1개 만든다.
AbstractDisplay d2 = new StringDisplay(“Hello, world.”);
// “안녕하세요.”를 가진 StringDisplay의 인스턴스를 1개 만든다.
AbstractDisplay d3 = new StringDisplay(“안녕하세요.”);
d1.display(); // d1, d2, d3 모두 AbstractDisplay의 하위클래스의 인스턴스이기 때문에
d2.display(); // 상속한 display메소드를 호출할 수 있다.
d3.display(); // 실제 동작은 CharDisplay나 StringDisplay에서 결정한다.
}
}
728x90
'개발 > 디자인 패턴' 카테고리의 다른 글
[Java 언어로 배우는 디자인 패턴 입문] 인스턴스 만들기 6. Prototype (0) | 2021.01.08 |
---|---|
[Java 언어로 배우는 디자인 패턴 입문] 인스턴스 만들기 5. Singleton (0) | 2021.01.07 |
[Java 언어로 배우는 디자인 패턴 입문] 하위 클래스 위임 4. Factory Method (0) | 2021.01.07 |
[Java 언어로 배우는 디자인 패턴 입문] 입문 2. Adapter- 재이용 (0) | 2021.01.04 |
[Java 언어로 배우는 디자인 패턴 입문] 입문 1. Iterator - 순서대로 처리 (0) | 2021.01.03 |
댓글