[디자인패턴] 템플릿 메소드 패턴 (Template Method Pattern)

koline·2023년 9월 12일
0

디자인패턴

목록 보기
23/24

템플릿 메소드 패턴


어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴이다.

일반적으로 상위 클래스(추상 클래스)에는 추상 메서드를 통해 기능의 골격을 제공하고, 하위 클래스(구체 클래스)의 메서드에는 세부 처리를 구체화하는 방식으로 사용하며 코드 양을 줄이고 유지보수를 용이하게 만드는 특징을 갖는 패턴이다.

즉, 여러 클래스에서 공통으로 사용하는 메서드를 템플릿화 하여 상위 클래스에서 정의하고, 하위 클래스마다 세부 동작 사항을 다르게 구현하는 패턴이라고 볼 수 있다.



구조


  1. AbstractClass(추상 클래스) : 템플릿 메소드를 구현하고, 템플릿 메소드에서 돌아가는 추상 메소드를 선언한다. 이 추상 메소드는 하위 클래스인 ConcreteClass 역할에 의해 구현된다.
  2. ConcreteClass(구현 클래스) : AbstractClass를 상속하고 추상 메소드를 구체적으로 구현한다. ConcreteClass에서 구현한 메소드는 AbstractClass의 템플릿 메소드에서 호출된다.

훅(hook) 메소드는 부모의 템플릿 메서드의 영향이나 순서를 제어하고 싶을때 사용되는 메서드 형태를 말한다.

예를 들어, 템플릿 메서드 내에 실행되는 동작을 hook1() 이라는 메서드의 참, 거짓 유무에 따라 다음 스텝을 어떻게 이어나갈지 지정한다. 이를 통해 자식 클래스에서 좀더 유연하게 템플릿 메서드의 알고리즘 로직을 다양화 할 수 있다는 특징이 있다.

훅 메소드는 추상 메소드가 아닌 일반 메소드로 구현하는데, 선택적으로 오버라이드 하여 자식 클래스에서 제어하거나 아니면 놔두거나 하기 위해서 이다.



구현


// Teacher.java (AbstractClass)
public abstract class Teacher {

    public final void startClass() {
        enterClassroom();
        teach();
        leaveClassroom();
    }
    
    public void enterClassroom() {
        System.out.println("[Teacher] enters classroom...");
    }

    public void leaveClassroom() {
        System.out.println("[Teacher] leaves classroom...");
    }

    abstract void teach();
}

// EnglishTeacher.java (ConcreteClass)
public class EnglishTeacher extends Teacher {
    @Override
    public void teach() {
        System.out.println("[EnglishTeacher] teaches English...");
    }
}

// MathTeacher.java (ConcreteClass)
public class MathTeacher extends Teacher {
    @Override
    public void teach() {
        System.out.println("[MathTeacher] teaches Mathematics...");
    }
}

// Client.java (Client)
public class Client{
    public static void main(String[] args) {
        Teacher engTeacher = new EnglishTeacher();
        Teacher mathTeacher = new MathTeacher();

        engTeacher.startClass();
        mathTeacher.startClass();
    }
}

// 실행 결과
[Teacher] enters classroom...
[EnglishTeacher] teaches English...
[Teacher] leaves classroom...
[Teacher] enters classroom...
[MathTeacher] teaches Mathematics...
[Teacher] leaves classroom...

우선 추상클래스로 Teacher를 정의해주고 일련의 처리 과정을 정의 및 구현한다. 그 중 구체 클래스에 따라 다르게 처리되는 메소드만 abstract로 정의하여 자식 클래스에서 세부적으로 구현할 수 있게 남겨두고, 정의된 메소드들을 처리 흐름에 따라 처리하는 메소드(Template Method)를 구현한다. Client는 템플릿 메소드를 호출하여 일련의 프로세스를 수행한다.

만약 구체들이 공통적으로 특정 기능을 수행하는데 하나의 구체 클래스가 다른 방식으로 해당 기능을 수행한다면 다음과 같이 오버라이딩하여 재정의 해줄수 있다.

예를 들어, 국어 선생님은 수업이 끝나도 교실을 떠나지 않고 계속 반에 머물러 있는 특성이 있다고 가정해보자.

// KoreanTeacher.java (ConcreteClass)
public class KoreanTeacher extends Teacher {
    @Override
    public void leaveClassroom() {
        System.out.println("[KoreanTeacher] I don't wanna leave, I am staying here,,, ");
    }

    @Override
    public void teach() {
        System.out.println("[KoreanTeacher] teaches Korean...");
    }
}

// Client.java
public class Client{
    public static void main(String[] args) {
        Teacher engTeacher = new EnglishTeacher();
        Teacher mathTeacher = new MathTeacher();
        Teacher korTeacher = new KoreanTeacher();

        korTeacher.startClass();
        engTeacher.startClass();
        mathTeacher.startClass();
    }
}

// 실행 결과
[Teacher] enters classroom...
[KoreanTeacher] teaches Korean...
[KoreanTeacher] I don't wanna leave, I am staying here,,,
[Teacher] enters classroom...
[EnglishTeacher] teaches English...
[Teacher] leaves classroom...
[Teacher] enters classroom...
[MathTeacher] teaches Mathematics...
[Teacher] leaves classroom...

국어선생님이 교실을 떠나지 않고 남은 두 수업을 참관하게 됬다..


목적

  1. 클라이언트가 알고리즘의 특정 단계만 확장하고, 전체 알고리즘이나 해당 구조는 확장하지 않도록 할때
  2. 동일한 기능은 상위 클래스에서 정의하면서 확장, 변화가 필요한 부분만 하위 클래스에서 구현할 때

장점

  1. 클라이언트가 대규모 알고리즘의 특정 부분만 재정의하도록 하여, 알고리즘의 다른 부분에 발생하는 변경 사항의 영향을 덜 받도록 한다.
  2. 상위 추상클래스로 로직을 공통화 하여 코드의 중복을 줄일 수 있다.
  3. 서브 클래스의 역할을 줄이고, 핵심 로직을 상위 클래스에서 관리하므로서 관리가 용이해진다
    3-1. 헐리우드 원칙 (Hollywood Principle) : 고수준 구성요소에서 저수준을 다루는 원칙 (추상화에 의존)

단점

  1. 알고리즘의 제공된 골격에 의해 유연성이 제한될 수 있다.
  2. 알고리즘 구조가 복잡할수록 템플릿 로직 형태를 유지하기 어려워진다.
  3. 추상 메소드가 많아지면서 클래스의 생성, 관리가 어려워질 수 있다.
  4. 상위 클래스에서 선언된 추상 메소드를 하위 클래스에서 구현할 때, 그 메소드가 어느 타이밍에서 호출되는지 클래스 로직을 이해해야 할 필요가 있다.
  5. 로직에 변화가 생겨 상위 클래스를 수정할 때, 모든 서브 클래스의 수정이 필요 할수도 있다.
  6. 하위 클래스를 통해 기본 단계 구현을 억제하여 리스코프 치환 법칙Visit Website을 위반할 여지가 있다.



참고


[디자인패턴] 디자인패턴이란? - 생성패턴, 구조패턴, 행위패턴

템플릿 메소드(Template Method) 패턴 - 완벽 마스터하기

[Design Pattern] 템플릿 메소드 패턴(Template Method Pattern)에 대하여

profile
개발공부를해보자

0개의 댓글