반응형
SMALL
정말 오랜만에 글을 작성하네요-_-
오늘의 학습 주제는
디자인 패턴 중 Strategy 패턴입니다
Stratey는 전략으로
적을 이기기 위한 작전이나
군대를 움직일 때의 방책 등을 의미합니다
프로그래밍에서 전략은
아무래도 알고리즘(Algorithm)이 되겠네요
Strategy 패턴은
이 알고리즘을 구현한 부분을
모두 교환할 수 있는 패턴입니다
먼저 Strategy 패턴의 역할들을 정리하면
다음과 같습니다
역할 | 설명 |
Strategy(전략) | Strategy는 전략을 이용하기 위한 인터페이스를 결정 |
Concrete Strategy(구체적인 전략) | Strategy의 인터페이스를 실제로 구현 |
Context(문맥) | Context는 Strategy를 이용하는 역할 |
역시 직접 구현을 해봐야 알 수 있겠죠?^^;
1. 클래스(Class) Hand.java
package strategyPattern;
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 static final String[] name = {
"주먹", "가위", "보",
};
private int handvalue;
private Hand(int handvalue) {
this.handvalue = handvalue;
}
public static Hand getHand(int handvalue) {
return hand[handvalue];
}
public boolean isStrongerThan(Hand h) {
return fight(h) == 1;
}
public boolean isWeakerThan(Hand h) {
return fight(h) == -1;
}
private int fight(Hand h) {
if ( this == h ) {
return 0;
} else if ( (this.handvalue + 1) % 3 == h.handvalue ) {
return 1;
} else {
return -1;
}
}
public String toString() {
return name[handvalue];
}
}
2. 클래스(Class) Player.java
package strategyPattern;
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 Hand nextHand() {
return strategy.nextHand();
}
public void win() {
strategy.study(true);
wincount++;
gamecount++;
}
public void lose() {
strategy.study(false);
losecount++;
gamecount++;
}
public void even() {
gamecount++;
}
public String toString() {
return "[" + name + ":" + gamecount + " games, " + wincount + " win, " + losecount + " lose]";
}
}
3. 인터페이스(Interface) Strategy.java
package strategyPattern;
public interface Strategy {
public abstract Hand nextHand();
public abstract void study(boolean win);
}
4. 클래스(Class) WinningStrategy.java
package strategyPattern;
import java.util.*;
public class WinningStrategy implements Strategy {
private Random random;
private boolean won = false;
private Hand prevHand;
public WinningStrategy(int seed) {
random = new Random(seed);
}
public Hand nextHand() {
if ( !won ) {
prevHand = Hand.getHand(random.nextInt(3));
}
return prevHand;
}
public void study(boolean win) {
won = win;
}
}
5. 클래스(Class) ProbStrategy.java
package strategyPattern;
import java.util.*;
public class ProbStrategy implements Strategy {
private Random random;
private int prevHandValue = 0;
private int currentHandValue = 0;
private int[][] history = {
{ 1, 1, 1, },
{ 1, 1, 1, },
{ 1, 1, 1, },
};
public ProbStrategy(int seed) {
random = new Random(seed);
}
public Hand nextHand() {
int bet = random.nextInt(getSum(currentHandValue));
int handvalue = 0;
if ( bet < history[currentHandValue][0] ) {
handvalue = 0;
} else if ( bet < history[currentHandValue][0] + history[currentHandValue][1] ) {
handvalue = 1;
} else {
handvalue = 2;
}
prevHandValue = currentHandValue;
currentHandValue = handvalue;
return Hand.getHand(handvalue);
}
private int getSum(int hv) {
int sum = 0;
for ( int i = 0; i < 3; i++ ) {
sum += history[hv][i];
}
return sum;
}
public void study(boolean win) {
if ( win ) {
history[prevHandValue][currentHandValue]++;
} else {
history[prevHandValue][(currentHandValue + 1) % 3]++;
history[prevHandValue][(currentHandValue + 2) % 3]++;
}
}
}
6. 클래스(Class) Test.java
import strategyPattern.*;
public class Test {
public static void main(String[] args) {
/* strategy Pattern */
int seed1 = 314;
int seed2 = 15;
Player player1 = new Player("One", new WinningStrategy(seed1));
Player player2 = new Player("Two", new ProbStrategy(seed2));
for ( int i = 0; i < 10000; i++ ) {
Hand nextHand1 = player1.nextHand();
Hand nextHand2 = player2.nextHand();
if ( nextHand1.isStrongerThan(nextHand2) ) {
System.out.println("Winner:" + player1);
player1.win();
player2.lose();
} else if ( nextHand2.isStrongerThan(nextHand1) ) {
System.out.println("Winner:" + player2);
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());
}
}
위의 코드를 보시면
Strategy 패턴은 알고리즘의 부분을
다른 부분과 분리해서 알고리즘의
인터페이스 부분만을 규정하고
위임에 의해 알고리즘을 이용합니다
위임은 느슨한 연결이므로
알고리즘을 용이하게 교환할 수 있습니다
위임에 대해서는 지난 Adapter 패턴에서 확인!!
2020/06/09 - [Java] - [Design Pattern] 어댑터 패턴(Adapter Pattern)
이 패턴을 이용한다면
정렬(Sort) 알고리즘들을
비교 분석하는데도 이용 가능할 것 같네요
시간이 난다면 한번 해봐야겠어요-_-
아무튼 오늘의 학습을 마치겠습니다
그럼 이만-_-
반응형
LIST
'Java' 카테고리의 다른 글
[Design Pattern] 데코레이터 패턴(Decorator Pattern) (0) | 2020.07.07 |
---|---|
[Design Pattern] 복합체 패턴(Composite Pattern) (0) | 2020.07.05 |
[Design Pattern] 브릿지 패턴(Bridge Pattern) (0) | 2020.06.23 |
[Design Pattern] 추상적인 공장 패턴(Abstract Factory Pattern) (0) | 2020.06.21 |
[Design Pattern] 빌더 패턴(Builder Pattern) (0) | 2020.06.15 |