Patterns

Template Method - 하위 클래스에서 구체적으로 처리하기

Caprica Six 2013. 5. 6. 17:56

Problem

자판기 사업을 새로 시작한 A씨는 커피와 레몬차를 판매하기로 결정하고 이를 제어할 자판기 제어 프로그램을 개발하도록 시스템 개발자에게 요구했고 아래와 같이 시스템이 개발되었다. 



Coffee & Tea 조리 메뉴얼

Coffee 조리법

물을 끓인다.

끊인 물에 커피를 넣는다.

컵에 커피를 붓는다.

설탕 및 우유를 추가한다.

Tea 조리법

물을 끓인다.

끓인 물에 Tea를 우려낸다.

컵에 Tea를 붓는다.

레몬을 추가한다.



솔루션 찾기 (문제해결 실습)

▶ 추상화 또는 일반화 하기

커피와 레몬차를 조리하는 조리법을 기준으로 추상화 할 수 있는 부분을 찾아 이들의 관계를 다이어그램에 표현하시오.

표현된 다이어그램을 기준으로 구현하고 제대로 동작하는지 여부를 확인하시오.

▶ 알고리즘 캡슐화 하기

커피와 레몬차 조리법의 알고리즘의 단계를 정의하고 하위 클래스에서 하나 또는 그 이상의 단계를 구현하도록 한다.

알고리즘 캡슐화 하기 이전과 이후를 비교해 보아라.


솔루션 발표

문제해결을 위해 디자인한 다이어그램과 개발 소스를 기준으로 발표









패턴소개 - Template Method 패턴


의도

- 오퍼레이션에 알고리즘의 기본 골격 구조를 정의

- 구체적인 단계는 하위클래스에 정의

- Template Method 클래스의 하위클래스는 알고리즘의 구조를 변경하지 않고 알고리즘의 처리 단계를 재정의

동기

Problem을 통해서 나타난 문제점을 Template Method 패턴을 통해 그 대안을 찾고자 한다.

- 추상화 또는 일반화 하기

- 알고리즘 캡슐화 하기 (Encapsulating Algorithms)



추상화 또는 일반화 하기

커피와 레몬차 조리법을 보면 공통된 행위를 찾을 수 있음.

즉, 물을 끓이거나 컵에 담는 행위는 동일하고 이를 추상클래스의 행위로 추출



prepareRecipe() 추상화 하기

커피와 레몬차의 조리법의 알고리즘을 살펴보면 동일한 흐름을 가지고 있음.

이를 통해서 prepareRecipe()를 추상화 방안 고려


커피와 레몬차 조리법 알고리즘 - prepareRecipe

1. 물을 끓인다.

2. 커피 또는 차를 추출하여 뜨거운 물에 넣는다.

3. 음료조리 결과를 컵에 담는다.

4. 기호에 맞게 음료에 첨가물을 넣는다.


1,3 : 이미 추상클래스 내에 정의되어있다.

2,4 : 추상클래스에 정의되지 않았지만 알고리즘은 동일하다. 단지 음료마다의 차이만 있을 뿐


알고리즘 캡슐화 하기 (Encapsulating Algorithms)

2,4의 행위를 좀 더 일반화 시켜야함





Templete 메소드와 Hook 메소드

▶ 템플릿 메소드는 알고리즘 단계를 정의하고 하나 또는 그 이상의 단계를 하위클래스에서 구현하도록 제공.

▶ 훅 메소드는 추상클래스에 정의된 메소드들 중에서 구현이 비어있거나 기본 구현만 되어 있는 메소드를 의미.



prepareRecipe() 메소드는 템플릿 메소드이다. 그 이유는 전체를 수행하는 메소드이고 또한 알고리즘에 대한 템플릿을 제공하기 때문이다.

템플릿에서 알고리즘의 각 단계는 메소드에 의해서 표현된다.


훅 메소드는 하위클래스에서 알고리즘의 변화를 주기 위해서 구현할 수도 있고, 그렇지 않다면 훅 메소드를 무시할 수 있다.


customerWantsCondiments() 메소드는 하위클래스에서 알고리즘 변화가 필요할 경우 구현할 수 있다. 원하지 않을 경우에는 기본적인 구현이 있으므로 알고리즘 수행에 영향이 없다.



할리우드 원칙 (Hollywood Principle)

의존성 문제로 고수준의 구성요소가 저수준의 구성요소에 의존하고 반대로 저수준의 구성요소가 고수준의 구성요소에 의존하게 되면 의존성이 꼬이게 됨.

이러한 복잡한 문제를 처리하기 위한 원칙을 말함.


WIKIPEDIA http://en.wikipedia.org/wiki/Hollywood_principle


The Hollywood Principle 

"Do not call us, we will call you."


Template Method 패턴에서도 템플릿메소드를 포함하고 있는 상위클래스가 전체 알고리즘을 제어하고 하위클래스는 알고리즘의 각 단계를 구현하고 있어 할리우드 원칙을 적용한 좋은 예이다.



High-Level Component는 알고리즘 시작과 방법을 제어한다.

Low-Level Component는 각각 자신의 알고리즘에 충실하면 된다.

Low-Level Component는 절대 직접 High-Level Component를 호출할 수 없다.





적용

▶ 알고리즘의 변하지 않는 부분을 한 번 정의하고 다양해질 수 있는 부분을 하위클래스에서 정의할 수 있도록 구현하고자 할 때

▶ 하위클래스 사이의 공통적인 행위를 추출하여 하나의 공통 클래스로 정의할 때

- 일반화를 위한 리펙토링의 예라고 볼 수 있음

- 기존 코드에서의 차이를 식별한 후 이를 새로운 오퍼레이션으로 구현할 수 있음

- 차이를 보이는 부분을 템플릿메소드로 정의하고 나중에 상속받은 하위클래스가 정의하는 오퍼레이션을 호출하게 함

▶ 하위클래스 확장을 제어할 수 있음

- 템플릿 메소드가 어떤 특정한 시점에 훅(Hook) 메소드를 호출하도록 정의

- 실제로 이 훅(Hook) 메소드가 호출되는 순간 새로운 확장이 이루어짐



클래스 구조