도서 요약 / / 2023. 1. 15. 21:10

[JAVA 언어로 배우는 디자인 패턴 입문] Template Method 패턴

'JAVA 언어로 배우는 디자인 패턴 입문'의 내용을 정리한 것입니다.

Template Method 패턴

  • 템플릿이란 문자 모양대로 구멍이 난 얇은 플라스틱 판이다.
  • 템플릿 구멍을 보면 어떤 형태의 문자인지 알 수 있지만, 실제로 어떤 문자가 될지는 구체적인 필기도구가 정해지기 전까지는 모른다.
  • 사인펜을 사용하면 사인펜으로 쓴 문자가, 연필을 사용하면 연필로 쓴 문자가 되며, 색연필을 사용하면 색깔이 있는 문자가 된다.

 

 

Template Method 패턴이란 무엇인가?

  • 상위 클래스 쪽에 템플릿이 될 메소드가 정의되어 있고, 그 메소드 정의에 추상 메소드가 사용된다.
  • 따라서 상위 클래스의 코드만 봐서는 최종적으로 어떻게 처리되는지 알 수 없다.
  • 상위 클래스로 알 수 있는 것은 추상 메소드를 호출하는 방법뿐이다.
  • 하위 클래스에서 메소드를 구현하면 구체적인 처리 방식이 정해진다.

예제 프로그램

이 책의 예제는 '문자나 문자열을 5번 반복해서 표시'하는 프로그램이다.

여기서는 AbstractDisplay, CharDisplay, StringDisplay, Main이라는 네 개의 클래스가 등장한다.

이름 설명
AbstractDisplay 메소드 Display만 구현된 추상 클래스
CharDisplay 메소드, open, print, close를 구현하는 클래스
StringDisplay 메소드, open, print, close를 구현하는 클래스
Main 동작 테스트용 클래스

 

AbstractDisplay 클래스

public abstract class AbstractDisplay {

    // open, print, close는 하위 클래스에 구현을 맡기는 추상 메소드
    public abstract void open();

    public abstract void print();

    public abstract void close();

    // display는 AbstractDisplay에서 구현하는 메소드
    public final void display() {
        open();
        for (int i=0; i<5; i++) {
            print();
        }
        close();
    }
}

CharDisplay 클래스

public class CharDisplay extends AbstractDisplay {

    private char ch; // 표시해야 하는 문자

    public CharDisplay(char ch) {
        this.ch = ch;
    }

    @Override
    public void open() {
        System.out.print("<<"); // 시작 문자열 "<<"를 표시
    }

    @Override
    public void print() {
        // 필드에 저장해 둔 문자을 1회 표시
        System.out.print(ch);
    }

    @Override
    public void close() {
        // 종료 문자열 ">>"를 표시
        System.out.println(">>");
    }
}

출력 결과

<<<HHHHH>>>

StringDisplay

public class StringDisplay extends AbstractDisplay {

    private String string; // 표시해야 하는 문자열

    private int width; // 문자열의 길이

    public StringDisplay(String string) {
        this.string = string;
        this.width = string.length();
    }

    @Override
    public void open() {
        printLine();
    }

    private void printLine() {
        System.out.print("+");
        for (int i=0; i<width; i++) {
            System.out.print("-");
        }
        System.out.println("+");
    }

    @Override
    public void print() {
        System.out.println("|" + string + "|");
    }

    @Override
    public void close() {
        printLine();
    }
}

출력 결과

+-------------+
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
+-------------+

Main 클래스

public class Main {

    public static void main(String[] args) {
        // 'H'를 가진 CharDisplay 인스턴스를 하나 만든다.
        AbstractDisplay d1 = new CharDisplay('H');

        // "Hello world."를 가진 StringDisplay 인스턴스를 하나 만든다.
        AbstractDisplay d2 = new StringDisplay("Hello, world.");

        d1.display();
        d2.display();
    }
}

AbstractClass (추상 클래스) 역

  • 템플릿 메소드를 구현하며, 그 템플릿 메소드에서 사용할 추상 메소드를 선언
  • 이 추상 메소드는 하위 클래스인 ConcreteClass에서 구현된다.
  • AbstractDisplay 클래스가 이 역할

ConcretClass (구현 클래스) 역

  • AbstractClass 역에서 정의된 추상 메소드를 구체적으로 구현
  • 여기서 구현하는 메소드는 AbstractClass의 템플릿 메소드에서 호출된다.
  • CharDisplay와 StringDisplay 클래스가 이 역할

정리

  • Template Method 패턴을 왜 사용할까?
  • 공통적으로 사용하는 특정 알고리즘이 있다면 상위 클래스에 기술하고 하위 클래스에서 다른 동작만 나타내면 중복작업을 줄일 수 있다.
  • 대신 상위 클래스의 로직을 이해해야만 하위 클래스를 구현할 수 있다.



반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유