템플릿 메소드 패턴

정선호·2023년 5월 31일
0

Design Patterns

목록 보기
23/24

템플릿 메소드 패턴

위키피디아
설명 및 스도코드

  • 부모 클래스에서 알고리즘의 골격을 정의하지만, 해당 알고리즘의 구조를 변경하지 않고 자식 클래스들이 알고리즘의 특정 단계들을 오버라이드​(재정의)​할 수 있도록 하는 행동 디자인 패턴

템플릿 메소드의 구조

  • 추상 클래스(Abstract Class)
    • 알고리즘의 단계들의 역할을 하는 메서드들을 선언하며, 이러한 메서드를 특정 순서로 호출하는 실제 템플릿 메소드도 선언
    • 단계들은 Abstract로 선언되거나 일부 디폴트 구현을 갖는다
  • 구상 클래스(Concrete Class)
    • 모든 단계들을 오버라이드할 수 있지만 템플릿 메서드 자체는 오버라이드할 수 없다

템플릿 메소드의 적용

  • 클라이언트들이 알고리즘의 특정 단계들만 확장할 수 있도록 하고 싶을 때, 그러나 전체 알고리즘이나 알고리즘 구조는 확장하지 못하도록 하려고 할 때 사용
    • 템플릿 메서드는 모놀리식 알고리즘을 일련의 개별 단계들로 전환할 수 있도록 한다.
    • 이 알고리즘은 부모 클래스에서 정의된 구조를 그대로 유지하면서 자식 클래스들에 의해 쉽게 확장될 수 있다.
  • 약간의 차이가 있지만 거의 같은 알고리즘들을 포함하는 여러 클래스가 있는 경우에 사용
    • 알고리즘이 변경되면 모든 클래스를 수정해야 할 수도 있다.
    • 이러한 알고리즘을 템플릿 메서드로 전환하면 유사한 구현들이 있는 단계들을 부모 클래스로 끌어올릴 수 있으며, 그로 인해 코드 중복을 제거할 수 있다.
    • 자식 클래스 중 서로 코드가 다른 부분들은 자식 클래스들에 남겨놓을 수 있다.

다른 패턴과의 관계

  • 팩토리 메서드는 템플릿 메서드의 특수화라고 생각할 수 있다. 동시에 대규모 템플릿 메서드의 한 단계의 역할을 팩토리 메서드가 할 수 있다.
  • 템플릿 메서드는 상속을 기반으로 한다. 이 메서드는 자식 클래스들에서 알고리즘의 부분들을 확장하여 변경할 수 있도록 한다.
    • 전략 패턴은 합성을 기반으로 한다. 객체 행동의 일부분들을 이러한 행동에 해당하는 다양한 전략들을 제공하여 변경할 수 있다.
    • 템플릿 메서드는 클래스 수준에서 작동하므로 정적이다. 전략 패턴은 객체 수준에서 작동하므로 런타임에 행동들을 전환할 수 있도록 한다.

템플릿 메소드 패턴 예제

  • 추상 클래스
public abstract class Coffee {
  final void makeCoffee() {
    boilWater();
    putEspresso();
    putIce();
    putExtra();
  }
  
  // SubClass에게 확장/변화가 필요한 코드만 코딩하도록 한다.
  abstract void putExtra();
  
  // 공통된 부분은 상위 클래스에서 해결하여 코드 중복을 최소화 시킨다.
  private void boilWater() {
    System.out.println("물을 끓인다.");		
  }
  private void putEspresso() {
    System.out.println("끓는 물에 에스프레소를 넣는다.");		
  }
  private void putIce() {
    System.out.println("얼음을 넣는다.");		
  }
}
  • 구상 클래스들
public class IceAmericano extends Coffee{
  @Override
  void putExtra() {
    System.out.println("시럽을 넣는다.");		
  }
}

package TemplateMethodPattern;
 
public class IceLatte extends Coffee{
  @Override 
  void putExtra() {
    System.out.println("우유를 넣는다.");
  }
}
  • 클라이언트
public class CoffeeMain {
  public static void main(String[] args) {
    IceAmericano americano = new IceAmericano();
    IceLatte latte = new IceLatte();
    
    americano.makeCoffee();
    System.out.println("===");
    latte.makeCoffee();
  }
}
profile
학습한 내용을 빠르게 다시 찾기 위한 저장소

0개의 댓글