상세 컨텐츠

본문 제목

디자인패턴01 - Strategy Pattern(전략패턴) with JAVA

Design Pattern with Java & Swift

by 앱등개발자IOS 2022. 9. 29. 12:49

본문

객체지향 설계를 하며, 아래와 같이 fly()메서드를 Duck 추상클래스에 선언해주고, 

매 번 concrete class에서 override하며 정의해준다면, 

    단점

    - 1. 서브클래스에서 코드가 중복됨 ( 같은 fly()형태를 띠는 클래스들에 같은 코드를 중복해서 작성해야함 )

    - 2. 실행 시에 특징을 바꾸기 힘들다 ( 클래스 내부에 concrete하게 구현되므로 실행 중 행동의 특성을 바꿀 수 없다)

    - 3. 모든 subclass들이 fly()에 관하여 어떤 행동들을 하는지 다 알기 힘들다. ( 관리하기 어려움 )

 

# 이런 경우에는 fly()를 superClass에서 빼, Flyable 이라는 Interface를 만들어 각 Subclass가 Implement하게 한다면?

    => 해당 특성 (fly, quack)을 갖지 않을 subclass에 구현하지 않을 수 있다는 점은 개선

    ==>  But, 코드의 재사용은 하지 못하고, 모든 subclass에 중복적으로 구현해야하는 단점은 그대로

# 여기에 디자인 원칙을 적용해보자 

 - 디자인 원칙1 : 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분과 분리한다.

- 디자인 원칙2 : 구현보다는 인터페이스에 맞춰 프로그래밍 한다.

- 디자인 원칙3 : 상속보다는 composition을 사용한다.

 

아래와 같이, subclass마다 달라지는 부분인 FlyBehavior와 QuackBehavior를 Interface로 구성하고, 

각 행동마다의 class 집합을 구성한다.

=> 상속만을 사용할 때의 단점들 개선!

    - 1. 코드 중복 없이 코드 재사용 가능!

    - 2. 실행 시에 특징을 바꿀 수 있다! ( 멤버 변수로 존재하므로 )

    - 3. 모든 subclass들이 fly()와 같은 특정 행동에 관하여 어떤 행동들을 하는지 다 알 수 있다 (관리 쉬움)

아래처럼 Duck 의 서브클래스에서는, 각 서브클래스에 맞는 행동 클래스 Object 를 생성하여  superclass에 선언해놓은 인터페이스 타입이  가리키도록 한다. 

 

이렇게  Duck 클래스에 

    - 인터페이스 형식의 레퍼런스 변수 2개를 선언( object composition )

    - 행동은 행동 클래스에 위임 (delegation)

 

==> 이것이 전략 패턴이며, 많은 디자인 패턴이 전략패턴에 기인한다.

 

{abstract} Duck 클래스 다이어그램을 확인해보면, setFlyBehavior(), set~~ 메서드들을 확인할 수 있다.

이는 실행 중 동적으로 Duck의 subclass 인스턴스들이 행동 관련 클래스를 갈아끼울 수 있게 하기 위함.

 

 

정리 :  전략패턴은,

        1.  변하는 알고리즘군을 별도의 클래스 집합으로 캡슐화,

        2. 이 알고리즘군을 사용하는 객체에서 올바른 행동 인터페이스 구현하고, 이곳에 composition된 객체에 알고리즘군 인스턴스를                  갈아끼우며 행동 실행을 delegation

 

   => Strategy Pattern은 알고리즘군을 정의, 캡슐화해서 각각의 알고리즘군을 관리, 수정, 사용할 수 있게 해준다.

          전략패턴을 사용하면 Client로부터 알고리즘을 분리해서 독립적으로 변경할 수 있다.

관련글 더보기