ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JAVA 디자인 스트래티지 패턴
    JAVA 2020. 1. 2. 17:25
    반응형

    1. 정의


     스트래티지 패턴(Strategy Pattern)
    알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다.
    스트래티지패턴을 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할수 있다.
    일반적으로 서브클래스를 만드는 방법을 대신하여 유연성을 극대화시키는 용도로 사용한다.
    디자인원칙 중 변경이 필요한 부분의 분리, 상속보다는 구성을 활용하라는 원칙을 적용한 패턴

    스트래티지 패턴은 정의와 같이 알리즘군을 정의하여 유연하게 알고리즘을 변경하는 용도로 사용되는 디자인 패턴입니다. 다음으로 제가 좋아하는 캐릭터인 아이언맨을 이용한 예시와 함께 스트래티지 패턴을 더 자세하게 알아보겠습니다.

    2. 예시: 개요


    아이언맨인 토니 스타크에게는 다양한 종류의 아이언맨 수트가 있습니다. 각각의 수트들은 외형은 비슷하더라도 버전별로 다른 기능을 가집니다.[1]


    <다양한 아이언맨의 수트들>[2]

    이러한 아이언맨의 수트들을 클래스로 구현해본다면 어떻게 될까요?  예를 들어 아래와 같은 수트를 구현한다고 가정해 보겠습니다.

    수트명 이동방법 공격방법
    마크1 비행 화염방사기
    마크7 비행 리펄서빔
    마크44 보행 맨손

    클래스의 상속을 통해 구현을 하자니 각각의 수트들이 가지는 기능들이 상이한 경우가 있고 인터페이스의 상속을 통해 구현을 하자니 같은 기능을 가지는 경우 그 기능을 재사용하지 못하고 수트별로 새롭게 구현을 해야합니다.또한  코드의 중복이 심해져 기능수정 시에도 어려움이 생기게 됩니다.

    이러한 경우 우리는 스트래티지 패턴을 통해 문제를 해결할 수 있습니다.

    2-1. 예시: UML


    먼저 이동과 공격 방법 기능을 그려보겠습니다.

    공격과 이동 인터페이스를 생성 후 이를 상속아 세부적인 기능을 정의하는 클래스들을 생성했습니다. 각 수트들은 세부적인 기능을 정의한 클래스를 이용하여 행동을 하게 됩니다. 이제 UML을 바탕으로 실제 코드를 구현해보겠습니다.

     

    2-2. 예시: 구현


    예시코드는 예시의 편의성과 패턴의 사용방법에 대하여 중점을 맞춘 것으로 실제 사용시에는 더 효율적으로 코드를 구성해서 사용해야 합니다. 코드예시를 보실 때는 ‘이렇게 동작하는구나’ 정도로 생각하며 봐주세요.

    1. 이동 및 공격방법 인터페이스

    public interface Move { public void doMove(); } public interface Attack { public void doAttack(); }

    2. 이동 인터페이스 구현 클래스

    public class Fly implements Move{ @Override public void doMove() { // TODO Auto-generated method stub System.out.println("이동방법 : 비행"); } } public class Work implements Move { @Override public void doMove() { // TODO Auto-generated method stub System.out.println("이동방법 : 보행"); } }

    3. 공격 인터페이스 구현 클래스

    public class FlameThrower implements Attack { @Override public void doAttack() { // TODO Auto-generated method stub System.out.println("공격방법 : 화염방사기"); } } public class RepulsorBeam implements Attack { @Override public void doAttack() { // TODO Auto-generated method stub System.out.println("공격방법 : 리펄서빔"); } }public class Punch implements Attack { @Override public void doAttack() { // TODO Auto-generated method stub System.out.println("공격방법 : 맨손"); } }

    4. 위 기능들을 이용하는 수트 클래스

    public class Suit { Move move; Attack attack; public Suit(String name, Move move, Attack attack){ System.out.println(name+" 착용"); this.move = move; this.attack = attack; } public void doMove(){ move.doMove(); } public void doAttack(){ attack.doAttack(); } }

    5. 메인 클래스

    public class IronMan { static public void main(String args[]){ Suit suit = new Suit("mark1",new Fly(), new FlameThrower()); suit.doMove(); suit.doAttack(); suit = new Suit("mark7",new Fly(), new RepulsorBeam()); suit.doMove(); suit.doAttack(); suit = new Suit("mark44",new Work(),new Punch()); suit.doMove(); suit.doAttack(); } }

    6. 결과

    mark1 착용 이동방법 : 비행 공격방법 : 화염방사기 mark7 착용 이동방법 : 비행 공격방법 : 리펄서빔 mark44 착용 이동방법 : 보행 공격방법 : 맨손

    IronMan 클래스에서 각각의 수트타입에 맞는 이동과 공격방법 알고리즘을 선택하여 적용함으로써 해당 기능이 변경되거나 추가되더라도 손쉽게 변경할 수 있음을 알 수 있습니다.

    3. 마무리


    이 외에도 스트래티지 패턴을 이용하면 마트의 할인시간 별 가격책정, 게임의 룰 설정, 캐릭터의 스킬셋 등  내부 알고리즘만 변경해서 사용해야하는 부분에서 많은 장점을 얻을 수 있습니다.

    반응형
Designed by Tistory.