본문 바로가기
Programming/DesignPattern

[디자인 패턴] 템플릿(Template) 메서드 패턴

by Blemish 2021. 5. 25.

 

Goal

  • 템플릿(Template) 메서드 패턴을 이해한다.

 

템플릿(Template) 메서드 패턴

전체적인 알고리즘은 상위 클래스에서 구현하면서 다른 부분은 하위 클래스에서 구현할 수 있도록 하는 디자인 패턴

클래스 다이어그램

 

 

템플릿 메서드 패턴은 전체적으로 동일하면서 부분적으로는 다른 구문으로 구성된 메서드의 코드 중복을 최소화할 때 유용하다. 동일한 기능을 상위 클래스에 정의하면서 확장/변화가 필요한 부분만 서브 클래스에서 구현할 수 있다.

 하위 클래스에 오버라이드될 필요가 있는 PrimitiveOperation 메서드를 primitive 또는 hook 메서드라고 부른다.

  • AbstractClass : 템플릿 메서드를 정의하는 클래스. 하위 클래스에 공통 알고리즘을 정의하고 하위 클래스에서 구현될 기능을 primitive 메서드 또는 hook 메서드를 정의하는 클래스
  • ConcreteClass :  상위 클래스에서 정의된 템플릿 메서드(templateMethod)의 전체적인 알고리즘에서 하위 클래스에서 적합하게 primitive 메서드나 hook 메서드를 오버라이드하는 클래스

 

Example

엘리베이터 제어 시스템에서 모터를 구동시키는 기능을 구현해보자.

클래스 다이어그램

모터가 움직일 때 문이 닫혀있는지 확인해야한다. 따라서 모터(HyundailMotor)와 문(Door)을 연관관계를 클래스 다이어그램으로 표시하였다. 

 문이 열려있을 때는 모터가 움직이면 안된다. 또한 모터가 움직이는 동안 문이 열리면 안되며 위/아래에 대한 방향 또한 확인을 해야 한다. 따라서 아래 그림처럼 각 상태에 대해서 Enumeration으로 정의하였다.

클래스 다이어그램을 기반으로 작성한 코드이다.

 

Motor의 Move 메서드를 호출하면 현재의 모터 상태, 문 상태를 확인하고 방향을 확인한 후에 모터를 가동시킨다.

 

Question

  • 사용한 모터는 현대 모터이다. 만약 다른 회사의 모터를 사용하려고 한다면?                                                    ->다른 모터(ex:LG)를 사용하게 되면 클래스를 추가하면 된다. 하지만 코드를 작성해보면 알겠지만 모터를 사용하는 기능(MoveMotor)을 제외하고 다수의 메서드들이 중복된다는 것을 확인할 수 있다. 일반적으로 코드 중복은 유지보수성을 약화시키므로 좋지 않다.

 

위의 문제를 해결하기 위해서는 상위 클래스(Motor)에서 전체적인 알고리즘을 구현하고 hook 메서드를 정의한 다음 하위 클래스(HyundaiMotor, LGMotor)에서 세부적인 기능을 구현해야 한다.

클래스 다이어그램

 

Motor라는 상위 클래스를 구현하고 LG와 현대 모터 기능의 공통적인 부분을 정의하였다. 그리고 세부적으로 확장/변화가 필요한 부분만 하위 클래스에 정의하였다.

 

Move 메서드를 보면 공통적인 알고리즘을 작성하였다. 또한 MoveMotor(hook) 메서드를 정의하였다.

LGMotor와 HyundaiMotor 클래스에서는 최대한 중복되는 코드는 최소화하였다. SetState는 Motor가 동작될 때 적용되어야 한다고 판단하여 MoveMotor 메서드 내부에서 호출되도록 설계하였다.

댓글