본문 바로가기

Design Patterns

Template Method Pattern ②

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
앞서 예를 들었던 Boy 와 Girl 클래스는 어떤 문제점이 있을까요?? 두 클래스에 굉장히 겹치는 부분들이 많다는 거죠.. 이런 겹치는 부분들이 생기면?? 상속을 활용한 재사용을 했습니다. 그래서 바꿔 봤습니다.. 상속을 통한.. ^^ 재사용을 위해서 말이죠~ 그래서 이렇게 상속의 구조로 고쳐봤습니다.

사용자 삽입 이미지

중복이 되는 코드인 고독을 느끼는 메소드와.. -_-;; (메소드명이 참;;) 사랑을 고백하는 메소드는 추상 클래스인 Human 클래스에 미리 정의를 해놓고.. findMates() 라는 메소드는 추상메소드로 상속 받는 서브 클래스에서 정의 하도록 했습니다. 이렇게 되면.. 공통적인 부분들을 확실히 분리해서 아름다운 코드가 되겠지요.. ^^

음.. 하지만 아쉬운게 있습니다. 서브 클래스에 있는 findGirlsWhoYouNeeds() 메소드나 findBoysWhoYouNeeds() 같은 메소드는 비슷한 행동이 잖아요?? 결국은 누구를 찾는 그런 행동이고.. 완전히 같다고 볼수는 없지만 정말 비슷합니다. 또한 구애를 하거나 관심을 끌거나.. 이것도 비슷한 행동인데.. 어떻게 확실히 정의 하기가 어렵습니다.

일단은 Human이라는 클래스에 추상메소드로 정의되어있는 findMates() 라는 메소드를 좀더 구체적으로 정의된 추상화(?) 를 해야하지 않나 하는 생각이 듭니다. 음.. 말로 하기가 어려우니 직접.. 한번 리팩토링을 해보겠습니다.

사용자 삽입 이미지
이렇게 바뀌었습니다. 어떤 부분이 바뀌었는지 Human 클래스만 보시면 되겠습니다. 왜냐? 나머지는 뻔하니까요 ^^ 아무 재미있는 패턴입니다 이번에도!!!

package templateMethod;

/**

* 클래스는 GoF 디자인 패턴 공부를 하기 위한 예제 소스입니다. 저작권은 있지만 마음껏 배포 수정 가능합니다. 한마디로 저작권

* 없습니다. -_-;;

*

* @since 2007. August. 10.

* @author Mr.Tint

*/

public abstract class Human {

          final void findMates() {

                    feelLoneliness();

                    findMatesWhoYouNeeds();

                    attractMatesInterest();

                    declareYourLove();

          }

          public abstract void findMatesWhoYouNeeds();

          public abstract void attractMatesInterest();

          public void feelLoneliness() {

                    System.out.println("고독함을 절실히 느낍니다.");

          }

          public void declareYourLove() {

                    System.out.println("당신의 사랑을 열렬히 고백합니다!");

          }

}

일단 findMates() 메소드의 내용이 살짝 바뀌었습니다. 이전의 Girl과 Boy 클래스의 메소드명이 살짝 달랐던 부분을 통일 시켜서 findMates() 메소드에서 호출이 되도록 하였고.. 미묘하게 달라지는 두 메소드인 findMatesWhoYouNeeds와 attractMatesInterest를 추상 메소드로 정의를 했으며 feelLoneliness와 declareYourLove는두 클래스에서 공통적이므로 이대로 두었습니다.

자 이렇게 한다고 뭐가 달라질까요 -_-?? 자자.. 달라집니다 달라져.. 템플릿 메소드 패턴이라잖아요?? 왜 템플릿 메소드 이냐 부터 한번 볼까요?? 과연 이중에서 템플릿 메소드는 어떤것일까요?? 그것은.. 바로..

findMate() 메소드 입니다. 템플릿의 사전적 의미가 일종의 틀이라고 하는데요.. findMate() 라는 것은 메소드가 네개나 들어가 있는 틀입니다. 이 틀 메소드에는 여러가지 메소드들이 순서대로 들어가 있는데.. 어떤 메소드는 해당 클래스에서 결정지어지기도 하고.. 어떤 메소드는 하위 메소드에서 정해지기도 합니다.

그럼 이렇게 템플릿 메소드 패턴을 사용함으로 얻어지는 효과는 뭘까요??

일단 이전에 만들었던 Girl Boy 클래스를 한번 보시면.. 서로 중복되는 코드가 있으며, 뭔가 내부적인 알고리즘, 예를들어 findMate() 라는 메소드가 바뀌게 된다면 서브 클래스 마다 일일이 다 바꿔줘야 합니다. 그리고 예를 들어 Girl, Boy 가 아니라 뭐 예를 들어서.. 음.. 아저씨나 아줌마의 클래스가 추가가 된다면, 코드 노가다가 많아 지게 되겠죠... 그리고 책에서는 알고리즘에 대한 지식과 구현 방법이 여러 클래스에 분산되어 진다고 합니다.

그럼 템플릿 메소드 패턴을 사용한 경우는 어떨까요?? 이전에 만들었던 구조의 단점들을 보완했겠죠..? 예를 들어서 Kids 라는 클래스가 추가된다면?? 어떨까요?

public class Kids extends Human {

   public void attractMatesInterest() {
       String actions[] = { "먹을 것을 양보합니다.", "친구네 집에 놀러갑니다." };
       System.out.println(actions[new Random().nextInt(actions.length)]);
   }

   public void findMatesWhoYouNeeds() {
       System.out.println("맘에 드는 사람을 찾습니다.");
   }
}

요런식으로 금새 만들어 줄 수 있습니다. 내부적인 코드 수정이나 이런 부분은 전혀 없지요.. ^^ 동일한 알고리즘을 따른다면, 서브클래스를 여러개 만들어서 행동들을 조금씩 다르게 하는것은 밥먹는거 만큼이나 쉬워집니다.