디자인 패턴 ~Strategy~

1. 소개



GoF의 디자인 패턴에서 Strategy 패턴을 요약합니다.

2. Strategy 패턴이란?


  • Strategy라는 영어 단어는 전략이라는 의미입니다. 프로그래밍의 경우는 알고리즘이라고 생각해도 좋은 것 같습니다.
  • 모든 프로그램이 문제를 해결하기 위해 작성되었습니다. 문제를 해결하기 위해 특정 알고리즘이 구현되었습니다. Strategy 패턴은 알고리즘을 구현한 부분을 살짝 교환할 수 있는 방식입니다.
  • GoF 디자인 패턴은 동작에 대한 디자인 패턴으로 분류됩니다.

  • 3. 샘플 클래스 다이어그램





    4. 샘플 프로그램



    싸움을하는 프로그램입니다. 무작위로 손을 내는 전략과 구만의 손을 내는 전략이 있습니다.

    4-1. Hand 클래스



    젠켄의 손을 나타내는 클래스입니다.

    Hand.java
    public class Hand {
    
        public static final int HANDVALUE_GUU = 0;
        public static final int HANDVALUE_CHO = 1;
        public static final int HANDVALUE_PAA = 2;
    
        public static final Hand[] hand = {
                new Hand(HANDVALUE_GUU),
                new Hand(HANDVALUE_CHO),
                new Hand(HANDVALUE_PAA),
        };
    
        private int handvalue;
    
        private Hand(int handvalue) {
            this.handvalue = handvalue;
        }
    
        public static Hand getHand(int handvalue) {
            return hand[handvalue];
        }
    
        public boolean isStrongerThan(Hand h) {
            // thisがhより強いときtrue
            return fight(h) == 1;
        }
    
        private int fight(Hand h) {
            if (this == h) {
                // 引き分け
                return 0;
            } else if ((this.handvalue + 1) % 3 == h.handvalue) {
                // thisの勝ち
                return 1;
            } else {
                // hの勝ち
                return -1;
            }
        }
    }
    

    4-2. Player 클래스



    싸움을 하는 플레이어를 나타내는 클래스입니다.

    Player.java
    public class Player {
    
        private String name;
        private Strategy strategy;
        private int wincount;
        private int losecount;
        private int gamecount;
    
        public Player(String name, Strategy strategy) {
            this.name = name;
            this.strategy = strategy;
        }
    
        public String getName() {
            return name;
        }
    
        public Hand nextHand() {
            return strategy.nextHand();
        }
    
        public void win() {
            wincount++;
            gamecount++;
        }
    
        public void lose() {
            losecount++;
            gamecount++;
        }
    
        public void even() {
            gamecount++;
        }
    
        public String toString() {
            return "[" + name + "] " + gamecount + " gemes, " + wincount + " win, " + losecount + " lose";
        }
    }
    

    4-3. Strategy 인터페이스



    젠켄의 「전략」을 나타내는 인터페이스입니다.

    Strategy.java
    public interface Strategy {
        public abstract Hand nextHand();
    }
    

    4-4. RandomStrategy 클래스



    무작위로 손을 내는 전략을 나타내는 클래스입니다.

    RandomStrategy.java
    import java.util.Random;
    
    public class RandomStrategy implements Strategy {
    
        public Hand nextHand() {
            Random random = new Random();
            return Hand.getHand(random.nextInt(3));
        }
    }
    

    4-5. GuuStrategy 클래스



    구만의 손을 내는 전략을 나타내는 클래스입니다.

    GuuStrategy.java
    public class GuuStrategy implements Strategy {
    
        public Hand nextHand() {
            return Hand.getHand(Hand.HANDVALUE_GUU);
        }
    }
    

    4-6. Main 클래스



    메인 처리를 실시하는 클래스입니다.

    Main.java
    public class Main {
    
        public static void main(String[] args) {
    
            Player player1 = new Player("Taro", new RandomStrategy());
            Player player2 = new Player("Hana", new GuuStrategy());
            for (int i = 0; i < 5; i++) {
                Hand nextHand1 = player1.nextHand();
                Hand nextHand2 = player2.nextHand();
                if (nextHand1.isStrongerThan(nextHand2)) {
                    System.out.println("Winner:" + player1.getName());
                    player1.win();
                    player2.lose();
                } else if (nextHand2.isStrongerThan(nextHand1)) {
                    System.out.println("Winner:" + player2.getName());
                    player1.lose();
                    player2.win();
                } else {
                    System.out.println("Even...");
                    player1.even();
                    player2.even();
                }
            }
    
            System.out.println("----- Total result -----");
            System.out.println(player1.toString());
            System.out.println(player2.toString());
        }
    }
    

    4-7. 실행 결과


    Winner:Taro
    Winner:Hana
    Even...
    Winner:Hana
    Even...
    ----- Total result -----
    [Taro] 5 gemes, 1 win, 2 lose
    [Hana] 5 gemes, 2 win, 1 lose
    

    5. 장점



    Strategy 패턴에서는 알고리즘의 부분을 다른 부분과 의식적으로 분리합니다. 그리고 알고리즘과의 인터페이스의 부분만을 규정해, 위양에 의해 알고리즘을 이용합니다.
    이것은 프로그램을 복잡하게 만드는 것처럼 보이지만 그렇지 않습니다. 예를 들어 알고리즘을 개선하고 더 빨리 만들고 싶다면 Strategy 패턴을 사용하고 있다면 Strategy 역할의 인터페이스를 변경하지 않도록 알고리즘을 추가하고 수정해야합니다. 위양이라는 느슨한 연결을 사용하고 있기 때문에 알고리즘을 준비로 전환할 수 있습니다.
    또, 게임 프로그램등에서는, 유저의 선택에 맞추어 난이도를 바꾸거나 하는데도 사용할 수 있습니다.

    6. GitHub


  • htps : // 기주 b. 코 m / 이타나카 730 /

  • 7. 디자인 패턴 목록


  • GoF 디자인 패턴 요약

  • 8. 참고



    이번 기사 및 샘플 프로그램은 이하의 서적을 바탕으로 작성하였습니다.
  • Java 언어로 배우는 디자인 패턴 입문

  • 매우 이해하기 쉽고 공부가되었습니다. 감사합니다.
    디자인 패턴이나 샘플 프로그램에 대한 설명이 상세하게 쓰여져 있으므로, 꼭 서적의 분도 봐 주세요.

    좋은 웹페이지 즐겨찾기