본문 바로가기
Design Pattern/Behavioral Design

[Design Pattern] (Behavioral) 템플릿 메서드 패턴(Template Method Pattern)

by song.ift 2023. 3. 27.

디자인 패턴 유형

  • Creation Design Pattern
    • 객체의 생성에 관련된 패턴
    • 객체의 생성 로직을 숨김으로써 유연성을 향상시킨다.
  • Strutural Design Pattern
    • 클래스와 객체의 구성에 관련된 패턴
  • Behavioral Design Pattern
    • 객체와 객체 간의 통신에 관련된 패턴

 

[Behavioral Design Pattern] 템플릿 메서드 패턴(Template Method Pattern)

GOF의 디자인 패턴에서 템플릿 메소드 패턴을 다음과 같이 정의하고 있다.

객체의 연산에는 알고리즘의 뼈대만을 정의하고, 알고리즘 각 단계에서 수행할 구체적 처리는 서브클래스 쪽으로 미룬다.
알고리즘의 구조 자체는 그대로 놔둔 채 알고리즘 각 단계처리를 서브클래스에서 재정의할 수 있게 하는 패턴이다.

여러 단계로 정의된 알고리즘의 뼈대는 그대로 유지한 채, 알고리즘의 구체적인 구현은 여러가지 형태로 확장 가능하도록 만들어주는 패턴이다.

어떤 한 알고리즘을 이루는 부분 중 변하지 않는 부분을 한 번 정의해 놓고 다양해질 수 있는 부분은 서브클래스에서 정의할 수 있도록 남겨두고자 할 때 템플릿 메소드 패턴을 사용한다.

 

예제

다음의 간단한 예제를 통해 알아보겠다.

 

  • HouseTemplate (추상클래스) : 집짓기 알고리즘의 뼈대(처리 단계)를 정의하는 템플릿 메소드(buildHouse)를 구현한다. 또한 알고리즘 뼈대(처리 단계) 내의 기본 연산들(buildFoundations, buildWindows, buildWalls, buildPillars)을 정의하고, 일부는 구현을 제공한다.
  • WoodenHouse, GlassHouse (구체클래스) : 서브클래스마다 달라진 알고리즘 처리 단계를 수행하기 위한 기본 연산(buildWalls, buildPillars)을 구현한다.

 

추상 클래스인 HouseTemplate의 buildHouse() 메소드에는 다음과 같이 집을 짓는 과정의 뼈대 알고리즘이 정의되어 있다.

집짓기 뼈대 알고리즘 : buildFoundations -> buildPillars -> buildWalls -> buildWindows

이와 같이 집짓기 과정의 필수 처리 절차를 정의한 buildHouse()를 가리켜 템플릿 메소드(Template Method)라고 한다.

 

구체 클래스인 WoodenHouse, GlassHouse를 살펴보면 추상 클래스 HouseTemplate을 상속받아서 기본 연산 buildWalls와 buildPillars를 오버라이딩하여 WoodenHouse, GlassHouse 각각에 맞는 구현을 제공하고 있다.

 

class HouseTemplate {
    buildHouse() {
      this.buildFoundations();
      this.buildPillars();
      this.buildWalls();
      this.buildWindows();
    }

    buildFoundations() {
      console.log('Building Foundations')
    }

    buildWindows() {
      console.log('Building Windows')
    }

    buildWalls() {
      throw new Error('You have to build your own walls')
    }

    buildPillars() {
      throw new Error('You have to build your own pillars')
    }
}

class WoodenHouse extends HouseTemplate {
    constructor() {
      super();
    }

    buildWalls() {
      console.log('Building Walls for wooden house')
    }

    buildPillars() {
      console.log('Building Pillars for wooden house')
    }
}

class GlassHouse extends HouseTemplate {
    constructor() {
      super();
    }

    buildWalls() {
      console.log('Building Walls for glass house')
    }

    buildPillars() {
      console.log('Building Pillars for glass house')
    }
}

const woodenHouse = new WoodenHouse();
const glassHouse = new GlassHouse();
woodenHouse.buildHouse();
glassHouse.buildHouse();

/* (Console output)
Building Foundations
Building Pillars for wooden house
Building Walls for wooden house
Building Windows
Building Foundations
Building Pillars for glass house
Building Walls for glass house
Building Windows
*/

 

사용시 유의할 부분

템플릿 메소드 패턴에서는 서브클래스를 작성할 때 상위 추상클래스의 어떤 메소드가 abstract operation인지 hook operation인지를 정확하게 알고 있어야 추상클래스를 효과적으로 재사용할 수 있다.

  • abstract operation : 서브클래스에서 반드시 오버라이드하여 작성해주어야 하는 연산
  • hook operation : 서브클래스에서 필요에 따라 오버라이드 해도 되고 안해도 되는 연산

 

댓글