개발서적

GOF, Template Method

규동 2023. 11. 18. 21:48

의도

객체의 연산에는 알고리즘의 뼈대만 정의하고 각 단계에서 수행할 구체적 처리는 서브클래 쪽으로 미룬다.

알고리즘의 구조 자체는 그대로 놔둔 채 알고리즘 각 단계 처리를 서브클래스에서 정의할 수 있게 해준다.

구조

구조

AbstractClass

알고리즘의 뼈대를 정의하는 추상클래스이다.

  TemplateMethod()

   알고리즘의 뼈대인 함수가 Template Method 이다.

  PrimitiveOperation1(), PrimitiveOperation2()

  알고리즘(TemplateMethod)에서 사용하는 메서드

ConcreteClass

Template Method에서 사용하는 구체적인 로직을 구현하는 서브클래스이다.

 

간단한 예제

public abstract class Application {
	public void run() {
    	if(isCanStart()) {
            try {
                doSomething();
            }catch(Exception e) {
                handleException();
            }finally {
                logging();
            }
        }
    }
    
    public void logging() {
    	log.info("실행결과~");
    }
    
    public abstract boolean isCanStart();
    
    public abstract void doSomething();
    
    public abstract void handleException();
    
}

 

특정 로직을 실행시킨 후에 로깅을 공통적으로 해야할 때, 이런식으로 추상클래스를 정의하고

서브클래스로 isCanStart(), doSomething(), handleException() 메서드를 재정의해서 사용할 수 있을 것 같다.

활용성

  • 어떠한 알고리즘 중 변하지 않는 부분을 한 번 정의해놓고 변할 수 있는 부분을 서브클래스에서 정의할 수 있도록 할 때
  • 서브클래스 사이의 공통적인 행동을 추출하여 하나의 공통 클래스에 모아둠으로써 코드 중복을 피하고 싶을 때
  • 서브클래스의 확장을 제어할 수 있다.

결과

템플릿 메서드는 코드 재사용을 위한 기본 기술이다. 부모 클래스에 템플릿을 정의하고, 일부 변경되는 로직은 자식 클래스에 정의하는 것이다. 이렇게 하면 자식 클래스가 알고리즘의 전체 구조를 변경하지 않고, 특정 부분만 재정의할 수 있다. 결국 상속과 오버라이딩을 통한 다형성으로 문제를 해결하는 것이다. 하지만, 템플릿 메서드는 "할리우드 원칙"이라는 역전된 제어 구조를 끌어낸다. 즉, 부모클래스는 서브클래스에 정의된 연산을 호출할 수 있지만 반대 방향의 호출은 안 된다. 상속에서 오는 단점들을 그대로 안고간다. 특히 자식 클래스가 부모 클래스와 컴파일 시점에 강하게 결합되는 문제가 있다.

상속을 받는 다는 것은 특정 부모 클래스를 의존하고 있다는 것이다. 따라서 부모 클래스의 기능을 사용하든 사용하지 않든 간에 부모 클래스를 강하게 의존하게 된다. 여기에 강하게 의존한다는 뜻은 자식 클래스의 코드에 부모 클래스의 코드가 명확하게 적혀있다는 뜻이다. UML에서 상속을 받으면 삼각형 화살표가 자식→부모를 향하고 있는 것은 이런 의존관계를 반영하는 것이다.