템플릿의 기능을 가진 패턴.
상위클래스에 템플릿에 해당하는 메소드가 정의, 추상메소드가 사용.
상위 클래스의 프로그램만 보면 추상 메소드를 어떻게 호출하고 있는 알 수 있지만, 최종적으로 어떤 처리가 수행되는지는 알 수 없다.

추상메소드를 실제로 구현하는 것은 하위 클래스다. 서로 다른 하위 클래스가 서로 다른 구현을 하더라도 처리의 큰 흐름은 상위 클래스에서 결정한대로 이루어진다.

(파워포인트2007로 작성...연결선이 맘에들지 않는다.;)

클래스 일람
AbstractDisplay : 추상클래스로서 메소드 display만 구현되고 있다.
CharDisplay : 메소드 open,print,close를 구현
StringDisplay : 위와 같지만 printLine도 추가
Main : 동작 테스트용

//AbstractDisplay
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 메소드에서 구현되고 있는 내용.
    }
}

//CharDisplay
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(“>>”);                   // 종료 문자열 “>>”을 표시.
    }
}

//StringDisplay
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(「+「);              // 테두리의 모서리를 표현하는 “+” 마크를 표시.
    }
}

//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에서 결정한다.
    }
}



이 패턴을 이용하면 상위클래스의 템플릿메소드에서 알고리즘이 기술되어 있으므로, 하위 클래스측에서는 알고리즘을 일일이 기술할 필요가 없다.

상위클래스에서 하위 클래스에게 요청

-상위클래스에서 정의되어 있는 메소드를 하위클래스에서 이용할 수 있다
-하위클래스에 약간의 메소드를 기술해서 새로운 기능을 추가할 수 있다
-하위클래스에서 메소드를 오버라이드하면 동작을 변경할 수 있다.


추상클래스의 의의
추상메소드는 본체가 기술되어 있지 않아서 구체적인 처리내용을 알 수 없으나, 메소드의 이름을 결정하고 메소드를 사용한 템플릿메소드에 의해 처리를 기술하는 것은 가능하다.
실제의 처리 내용은 하위 클래스에서 결정하지만, 추상클래스의 단계에서 처리의 흐름을 형성하는 것은 중요하다.
AND