전체 흐름은 부모가 정하고 달라지는 단계만 자식이 채우게 하는 행위 패턴. 추상 클래스가 존재하는 가장 큰 이유이기도 하다.

고정된 순서와 달라지는 단계

바뀌지 않는 것과 바뀌는 것을 분리한다. 디자인 패턴의 첫 번째 원칙 그대로다. 자동차가 시동을 걸고 달리고 멈추고 끄는 순서는 변하지 않고, 어떻게 달리고 어떻게 멈추는지만 차마다 다르다. 공통 단계를 자식마다 다시 쓰지 않아도 되니 중복도 준다.

흐름을 고정하는 final

부모 클래스에 순서를 정한 메서드를 두고, 그 안에서 부르는 단계 중 일부를 추상 메서드로 남긴다.

abstract class Car {
    // 템플릿 메서드. 흐름은 여기서 고정된다
    public final void run() {
        startCar();
        drive();      // 자식마다 다르다
        stop();       // 자식마다 다르다
        turnOff();
    }
    abstract void drive();
    abstract void stop();
    void startCar() { ... }   // 공통
    void turnOff() { ... }    // 공통
}

자식은 drive()stop()만 구현하고 순서를 바꿀 수는 없다. final을 붙이는 이유가 여기 있다. 자식이 흐름 자체를 재정의하면 패턴의 의미가 사라진다.

자식에게만 여는 protected

자식만 쓸 수 있게 하고 싶은 메서드에는 protected를 붙인다. public이면 밖에서도 부를 수 있고 private이면 자식이 못 쓴다. 템플릿 메서드 패턴이 protected의 대표적인 쓰임새다.

상속으로 갈아 끼우기

데코레이터 패턴이 합성으로 기능을 덧붙이는 것이라면 템플릿 메서드는 상속으로 일부를 갈아 끼우는 것이다. 상속을 쓰는 만큼 결합이 강하므로 흐름이 정말 고정적일 때만 쓴다. 상속과 합성에 이어진다.

관련

출처