Tiny Star

🪄Interview/✏️Study

[CS STUDY INTERVIEW] 14주차 - 템플릿 메서드 패턴

청크 2024. 6. 19. 20:08

CS 스터디 14주차 

 

템플릿 메서드 패턴 


템플릿 메서드 패턴(Template Method Pattern)

템플릿 메서드 패턴(Template Method Pattern)은 객체지향 소프트웨어 설계 패턴 중 하나이다.

 

상위 클래스에서 알고리즘의 골격을 정의하고,  알고리즘의 일부 단계를 하위 클래스에서 구현하도록 하는 패턴으로

상위 클래스는 템플릿 메서드를 통해 알고리즘의 주요 단계를 정의하고, 하위 클래스는 이러한 단계를 구체적으로 구현한다.

 

프론트에서 주로 다루는 타임리프 같은 기능이라고 생각하면 된다.

타임리프는 HTML 파일에서 동적으로 데이터를 바인딩하고, 템플릿 상속 등의 기능으로 재사용 가능한 웹페이지를 설계한다.

템플릿 메서드 패턴과 이런 개념이 유사한 방식으로 설계되고 사용된다는 점을 대입해서 생각하면 조금  더 이해가 쉬울 것 같다.


템플릿 메서드 패턴의 사용방법

1. 상위 클래스 정의(알고리즘 구조 정의)

상위 클래스에서 알고리즘의 구조를 정의하고, 주요 단계를 메서드로 선언해준다.

2. 하위 클래스 구현(구현의 세부사항 위임)

상위 클래스에서 선언한 추상 메서드를 하위 클래스에서 각 단계를 구체적으로 구현한다.

3. 템플릿 메서드 호출 

클라이언트 코드에서 상위 클래스의 템플릿 메서드를 호출하여 알고리즘을 실행한다.

 

장점

1. 상위 클래스에서 알고리즘의 공통된 구조를 정의하기 때문에 알고리즘의 구조를 재사용하기 쉬워져 코드의 재사용성을 높인다.

2. 하위 클래스에서 알고리즘의 각 단계를 자유롭고 유연하게 구현할 수 있으며,

만약 알고리즘의 변경이 필요할 때는 하위 클래스만 수정해주면 되기 때문에 유지보수가 용이하다.

 

단점

1. 상위 클래스를 하위 클래스가 상속하기 때문에 만약 다중상속이 필요한 경우 모든 언어에서 지원이 되지 않는다.

2. 코드가 복잡해질수록 상-하위 클래스 간의 관계 또한 복잡해질 수 있다.


자바와 파이썬에서의 템플릿 메서드 패턴 사용

자바(JAVA)

1. 추상 클래스를 정의한다.

abstract class Game {
    // 템플릿 메서드
    public final void play() {
        initialize();
        startPlay();
        endPlay();
    }

    // 추상 메서드
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();
}

 

먼저, 앞서 설명했던 알고리즘의 기본 구조를 정의하는 추상클래스를 만들어준다.

이 클랫느는 템플릿 메서드와 알고리즘의 각 단계를 정의하는 추상 메서드들이 포함되어 있다.

 

public final void play()

이 메서드는 알고리즘의 기본 구조를 정의하고 final로 선언되어 하위 클래스에서 재정의할 수 없게된다.

이는 알고리즘의 순서와 구조가 변경되지 않도록 보장해주는 역할을 한다.

추상 메서드 initialize(), startPlay(), endPlay()

이 메서드들은 하위 클래스에서 구현해야 하는 미완성된 메서드들이며 각각의 메서드는 알고리즘의 특정 단계를 나타낸다.

 

 

2. 하위 클래스 정의를 한다.

class Cricket extends Game {
    @Override
    void initialize() {
        System.out.println("Cricket Game Initialized! Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Cricket Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Cricket Game Finished!");
    }
}

 

class Football extends Game {
    @Override
    void initialize() {
        System.out.println("Football Game Initialized! Start playing.");
    }

    @Override
    void startPlay() {
        System.out.println("Football Game Started. Enjoy the game!");
    }

    @Override
    void endPlay() {
        System.out.println("Football Game Finished!");
    }
}

각각의 하위 클래스는 상위 클래스에서 정의한 추상 메서드를 구체적으로 구현하며

각 하위 클래스는 특정 알고리즘의 구체적인 동작을 정의하여 메서드 사용이 가능하도록 한다.

 

두개의 각 하위클래스는 Game 클래스를 상속받는다.

initialize(), startPlay(), endPlay() 메서드를 오버라이드하여 구체적인 구현을 제공하고

각 메서드는 게임의 특정 단계를 나타내며, 구체적인 메시지를 출력하는 예시이다.

 

 

3. 클라이언트 코드

public class TemplatePatternDemo {
    public static void main(String[] args) {
        Game game = new Cricket();
        game.play();
        System.out.println();
        game = new Football();
        game.play();
    }
}

 

클라이언트 코드에서는 상위 클래스의 타입의 변수를 사용하여 하위 클래스의 인스턴스를 참조하고

템플릿 메서드를 호출하여 알고리즘을 실행한다.

 

코드를 하나씩 뜯어보면 이렇다.

 

Game game = new Cricket();: Cricket 클래스의 인스턴스를 생성하고, Game 타입의 변수 game에 할당하게 된다.

game.play();: play() 메서드를 호출하여 알고리즘을 실행하며

play() 메서드는 Cricket 클래스에서 구현된 initialize(), startPlay(), endPlay() 메서드를 차례로 호출한다.


game = new Football();: Football 클래스의 인스턴스를 생성하고, Game 타입의 변수 game에 할당한다.

game.play();: play() 메서드를 호출하여 알고리즘을 실행하며

play() 메서드는 Football 클래스에서 구현된 initialize(), startPlay(), endPlay() 메서드를 차례로 호출한다.

 

파이썬(PYTHON)

 

스터디원들이랑 실제 코드를 한번씩 실행해보기로 했는데, 나는 파이썬을 주로 다루고 있어서

파이썬으로 실제 코드를 작성해봤다.

 

참고로 적어두자면 

파이썬은 추상 클래스(abstract class)라는 기능을 제공하는데,  import로 abc 모듈을 가져와야 한다.( abc : abstract base class)

클래스의 ( )(괄호) 안에 metaclass=ABCMeta를 지정하고, 메서드를 만들 때 위에 @abstractmethod를 붙여서 추상 메서드로 지정하여

사용할 수 있다.

 

패턴의 순서는 자바와 동일.

 

 

def play(self)

자바와 마찬가지로 이 메서드는 알고리즘의 기본 구조를 정의하고 상속받은 클래스에서

이 메서드를 재정의할 수 없도록 하고 알고리즘의 순서와 구조를 변경하지 않는다.


추상 메서드 initialize(), start_play(), end_play()

이 메서드들은 하위 클래스에서 구현해야 하는건 자바와 동일하다.

 

다음 하위 클래스에서의 구현

 

Game 클래스를 상속받고 세개의 메서드를 오버라이드하여 구체적으로 구현했다.

 

 

마지막 클라이언트 코드

상위 클래스 타입의 변수에 하위 클래스의 인스턴스를 할당하고, play() 메서드를 호출하여 알고리즘을 실행할 수 있는 코드로 작성했다.

 

이와 같이 템플릿 메서드 패턴은 상위 클래스에서 알고리즘의 구조를 정의하고,

하위 클래스에서 구체적인 단계를 구현하도록 하여 코드의 재사용성과 유연성을 높힐 수 있다.