티스토리 뷰

Java

DesignPattern#02 Template Method Pattern

LichKing 2016. 3. 2. 15:40

자바에서 기 작성된 소스를 재사용하는 방법은 사용하고자 하는 클래스에게 상속하거나 혹은 인스턴스멤버로 합성(composite)하는 방법이 있다. 지난번 포스팅인 Strategy Pattern은 두 가지 방법중 합성을 선택해 외부에서 전략을 주입하며 사용하는 법에 대해 알아봤다.

이번에는 상속을 사용하는 패턴에 대해 알아보자. 바로 Template Method Pattern(이하 템플릿 메서드 패턴) 인데 이름에서 느껴지듯 기 작성된 소스(Template)가 존재하고 해당 소스에서 부분적으로 메서드를 오버라이딩하는 패턴이다. 이렇게 작성할 경우 전체적인 뼈대인 기존 소스는 동일하게 작동하며 오버라이딩한 부분만 구현클래스별로 작동할것이다. 코드로 살펴보자


abstract class A{ //추상클래스로 작성한다.

public int templateMethod(int num1, int num2){  //재사용하고자하는 template 메서드

System.out.println("입력받은 값 => [" + num1 + ", " + num2 + "]");

int result = calculation(num1, num2);

return result;

}


public abstract int calculation(int num1, int num2);    //오버라이딩에 의해 구현체가 바뀔수있는 추상메서드

}


class Sum extends A{

@Override

public int calculation(int num1, int num2){

return num1 + num2;    //더하기 연산을 하도록 오버라이딩

}

}


class Multi extends A{

@Override

public int calculation(int num1, int num2){

return num1 * num2;    //곱하기 연산을 하도록 오버라이딩

}

}


public class Test{

public static void main(String[] arg){

A a = new Sum();


System.out.println(a.templateMethod(5, 10));    //더하기 수행


a = new Multi();


System.out.println(a.templateMethod(5, 10));    //곱하기 수행

}

}


갑자기 예제를 짜려니까 너무 생각이 안나서 너무 간단하게 아닌가 싶기도하지만... 이런식으로 진행되게 된다. 굳이 추상메서드가 아니라도 오버라이딩이 가능하기때문에 templateMethod도 오버라이딩이 될수도있다는점을 명심하자. 오버라이딩을 막고 싶다면 templateMethod를 final로 선언하면 된다.


그리고 꼭 오버라이딩을 해야하는 추상메서드가 아니라 선택적으로 오버라이딩을 해야하는 hook메서드를 집어넣기도 한다.


abstract class A{ //추상클래스로 작성한다.

public int templateMethod(int num1, int num2){  //재사용하고자하는 template 메서드

System.out.println("입력받은 값 => [" + num1 + ", " + num2 + "]");

int result = calculation(num1, num2);

hook();

return result;

}


public abstract int calculation(int num1, int num2);    //오버라이딩에 의해 구현체가 바뀔수있는 추상메서드


public void hook(){}    //아무것도 하지않는 '구현' 메서드

}


class Multi extends A{

@Override

public int calculation(int num1, int num2){

return num1 * num2;    //곱하기 연산을 하도록 오버라이딩

}


@Override

public void hook(){

System.out.println("연산 종료");    //구현메서드이기때문에 필요에따라 오버라이딩 하면된다.

}

}


public class Test{

public static void main(String[] arg){

A a = new Multi();


System.out.println(a.templateMethod(5, 10));    //곱하기 수행

}

}


이 패턴은 상속을 이용하기때문에 이 패턴을 구현하기위해서는 다른 클래스는 상속받을수가 없다는 단점이 있다. effective java에서도 그렇고 하도여기저기서 상속은 가급적 쓰지말라고하다보니 상속은 일단 제끼고 생각하게되는 경향이 있는데 필요할땐 써야하지않겠는가? 디자인패턴을 공부하는것도 힘들지만 언제 어떤 패턴을 써야하는지 판단하는것도 참 힘든것 같다.

'Java' 카테고리의 다른 글

DesignPattern#04 Decorator Pattern  (0) 2016.03.10
DesignPattern#03 Template Callback Pattern  (0) 2016.03.04
DesignPattern#02 Template Method Pattern  (0) 2016.03.02
DesignPattern#01 Strategy Pattern  (0) 2016.03.01
MVC 구조에서 service와 serviceImpl  (37) 2016.02.27
tiles3 설정  (0) 2016.02.18
댓글
댓글쓰기 폼