티스토리 뷰

Java

DesignPattern#01 Strategy Pattern

LichKing 2016. 3. 1. 13:52

디자인패턴의 꽃이라 불리는 Strategy Pattern 에 대해 알아보자. 기본적으로 자바를 배울때 자바는 객체지향언어이고 그로인한 장점을 상속을 통해 이미 작성되어있는 코드를 재사용할 수 있는 장점이 있다고 배운다. Strategy Pattern은 그런 상속을 통한 소스 재사용을 상속이 아닌 합성(composite)을 통해 사용하는것에 초점을 맞춘다. 굳이 이렇게 거창하게 디자인패턴이라는 단어가 아니라도 다중상속이 지원되지않는 자바에서 상속 대신 합성을 사용하여 소스를 재사용하고자 하는 경우는 많다. 대표적으로 is a, has a 로 구분해서 상속과 합성을 알맞게 사용하자는 말이 있는데 합성이 구체적으로 뭔지부터 알아보자.


//getString() 을 재사용 하고싶다.

class A{

  public String getString(){

    return "Hello World";

  }

}


//상속을 이용한 방법

class B extends A{


}


//합성을 이용한 방법

class C{

  public String getString(){

    A a = new A();


    return a.getString();

  }

}


//테스트

public class Test{

  public static void main(String[] arg){

    B b = new B();

    C c = new C();


    System.out.println(b.getString());  //Hello World 출력!

    System.out.println(c.getString());  //Hello World 출력!

  }

}


두 경우 모두 A클래스 소스를 재사용함으로서 Hello World를 출력하게된다. 합성을 이용했을경우 변수도 선언해야하고 소스도 좀 더 길어지지만 단일상속만을 지원하는 자바에서 상속이라는 유일무이한 자원을 아껴두고있는 이점이 있다. 또한 상속같은 경우 상위 클래스와 하위 클래스간의 결합도가 높아져 재사용하고자하는 상위 클래스를 수정할 경우 하위클래스까지 영향을 미치게된다. Strategy Pattern은 합성과 다형성까지 이용해 언제든 재사용하고자 하는 객체를 교체해가며 필요한 전략(strategy)을 호출하는 패턴이다.


interface A{

  public String getString();

}


//인터페이스 A 구현

class B implements A{

  @Override

  public String getString(){

    return "Hello World";

  }

}


//인터페이스 A 구현

class C implements A{

  @Override

  public String getString(){

    return "Hello LichKing":

  }

}


//클라이언트 클래스

class D{

  A a;


  public void setA(A a){

    this.a = a;

  }


  public String playStrategy(){

    return a.getString();

  }

}


//테스트

public class Test{

  public static void main(String[] arg){

    D d = new D(); //클라이언트 객체 생성


    d.setA(new B()); //전략 전달

    System.out.println(d.playStrategy()); //전략 실행


    d.setA(new C()); //전략 교체

    System.out.println(d.playStrategy()); //전략 실행

  }

}


setter 메서드를 통해 필요할때마다 전략을 교체해가며 달라진 객체의 메서드를 호출하게된다. 전략을 사용하는 클라이언트 클래스인 D는 자신이 직접 전략객체를 생성해서 호출하는 것이 아니라 외부에서 주입받은 객체를 사용하기때문에 소스가 유연해지고 언제든 다른 객체를 주입받아(해당 인터페이스만 구현해준다면) 호출할수있기때문에 확장성도 뛰어나진다. 주입이라는 단어를 보니 떠오르는게 없는가? 스프링의 DI 원리가 바로 이 Strategy Pattern에 기반한 것이다. 이 패턴이 디자인패턴의 꽃이라 불리는 이유는 그만큼 객체지향설계원칙을 준수하고 널리 사용되기떄문일 것이다. 잘 익혀두고 사용하자.

'Java' 카테고리의 다른 글

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
String Class와 equals()  (0) 2015.12.02
댓글
댓글쓰기 폼