본문 바로가기

JAVA/디자인 패턴

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

반응형
행위 패턴(Behavioral Pattern)


템플릿 메서드 패턴(Template Method Pattern)은 객체 지향 디자인 패턴 중 하나로, 알고리즘의 일부분을 서브클래스에서 구현하도록 하는 패턴입니다.

이 패턴은 상위 클래스에서 알고리즘의 전체 구조를 정의하고, 일부 구체적인 단계를 하위 클래스에서 구현할 수 있도록 합니다. 즉, 템플릿 메서드 패턴을 사용하면 알고리즘의 구조를 유지하면서 일부 구현을 다른 클래스로 위임할 수 있습니다.

이 패턴의 핵심 아이디어는 알고리즘의 구조를 추상화하는 것입니다. 상위 클래스에서는 알고리즘의 전체 구조를 나타내는 메서드를 정의하고, 이 메서드 안에서는 구체적인 단계를 수행하는 추상 메서드를 호출합니다. 하위 클래스에서는 추상 메서드를 구현하여 전체 알고리즘을 완성합니다.

예를 들어, 게임 프로그램에서 여러 캐릭터를 생성하는 경우를 생각해보겠습니다. 각 캐릭터에는 공통된 초기화 과정이 있지만, 캐릭터의 종류에 따라 다르게 처리해야 합니다. 이 경우에는 템플릿 메서드 패턴을 사용하여 초기화 과정의 전체 구조를 정의하고, 종류에 따라 다르게 처리해야 하는 부분을 서브클래스에서 구현합니다.

이 패턴의 장점으로는 유지 보수성과 확장성이 향상됩니다. 알고리즘의 구조를 수정하지 않고도 서브클래스에서 구현한 구체적인 알고리즘을 추가하거나 변경할 수 있습니다. 또한, 코드의 중복을 줄일 수 있어 코드의 가독성을 향상시키고, 디버깅이 용이해집니다.

하지만, 이 패턴을 사용하면서 상위 클래스와 하위 클래스 사이의 결합도가 높아질 수 있습니다. 또한, 추상 클래스와 구체 클래스의 수가 늘어날 수 있기 때문에, 클래스의 수가 많아질 수 있습니다. 이러한 단점을 고려하여 적절한 상황에서 템플릿 메서드 패턴을 사용해야 합니다.

 

Template Method 패턴 예제

이 예제는 커피 제조 프로세스를 구현합니다. 커피 제조 과정은 동일하지만, 커피의 종류에 따라 커피를 내리는 시간이 다릅니다. 이 예제에서는 커피 제조 과정의 전체 구조를 정의하는 Coffee 클래스와, 커피 종류에 따라 내리는 시간을 구현하는 서브클래스인 AmericanoCoffee와 LatteCoffee 클래스를 구현합니다.

Diagrams



// Coffee 클래스 (추상 클래스)
public abstract class Coffee {
 
    // 템플릿 메서드 (커피 제조 과정의 전체 구조를 정의함)
    public final void prepareCoffee() {
        boilWater();
        brewCoffee();
        pourInCup();
        addMilkAndSugar();
        serveCoffee();
    }
 
    // 물 끓이기
    public void boilWater() {
        System.out.println("Boiling water");
    }
 
    // 커피 내리기 (추상 메서드, 하위 클래스에서 구현함)
    public abstract void brewCoffee();
 
    // 컵에 따르기
    public void pourInCup() {
        System.out.println("Pouring into cup");
    }
 
    // 우유와 설탕 추가하기 (오버라이드 가능)
    public void addMilkAndSugar() {
        System.out.println("Adding milk and sugar");
    }
 
    // 커피 제공하기
    public void serveCoffee() {
        System.out.println("Serving coffee");
    }
}
 
// AmericanoCoffee 클래스 (Coffee 클래스의 하위 클래스)
public class AmericanoCoffee extends Coffee {
 
    // 커피 내리기 (오버라이드)
    public void brewCoffee() {
        System.out.println("Dripping Coffee through filter");
    }
}
 
// LatteCoffee 클래스 (Coffee 클래스의 하위 클래스)
public class LatteCoffee extends Coffee {
 
    // 커피 내리기 (오버라이드)
    public void brewCoffee() {
        System.out.println("Brewing Espresso");
    }
 
    // 우유와 설탕 추가하기 (오버라이드)
    public void addMilkAndSugar() {
        System.out.println("Adding milk and sugar to latte");
    }
}
 
// 메인 클래스
public class Main {
 
    public static void main(String[] args) {
        // AmericanoCoffee 객체 생성
        Coffee americano = new AmericanoCoffee();
        System.out.println("Preparing Americano Coffee:");
        americano.prepareCoffee();
 
        System.out.println();
 
        // LatteCoffee 객체 생성
        Coffee latte = new LatteCoffee();
        System.out.println("Preparing Latte Coffee:");
        latte.prepareCoffee();
    }
}



위 예제에서는 Coffee 클래스를 추상 클래스로 선언하여, 템플릿 메서드인 prepareCoffee() 메서드를 구현합니다. 이 prepareCoffee() 메서드는 커피 제조 과정의 전체 구조를 나타내며, boilWater(), brewCoffee(), pourInCup(), addMilkAndSugar(), serveCoffee() 등의 메서드를 호출합니다. 이때 brewCoffee() 메서드는 추상 메서드로 선언되어 있으므로, 하위 클래스에서 반드시 구현되어야 합니다.

이 예제에서는 AmericanoCoffee 클래스와 LatteCoffee 클래스를 Coffee 클래스의 하위 클래스로 선언하여, 각각의 커피 종류에 따라 brewCoffee() 메서드를 구현합니다. 또한, LatteCoffee 클래스에서는 addMilkAndSugar() 메서드도 오버라이드하여 커피 제조 과정을 다르게 구현합니다.

Main 클래스에서는 AmericanoCoffee 객체와 LatteCoffee 객체를 생성하여, prepareCoffee() 메서드를 호출합니다. 이때, prepareCoffee() 메서드는 상위 클래스인 Coffee 클래스에서 정의된 템플릿 메서드를 실행하므로, 각각의 커피 종류에 따라 내리는 시간과 우유와 설탕을 추가하는 시간이 다르게 나타납니다.

이처럼 템플릿 메서드 패턴은 공통된 알고리즘을 가진 메서드를 상위 클래스에서 정의하고, 이를 하위 클래스에서 구체적으로 구현함으로써 코드의 재사용성과 확장성을 높일 수 있습니다.

반응형