设计模式-策略模式

策略模式

定义

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

类图

策略模式类图

Strategy(策略)

负责决定实现策略锁必需的接口

ConcreteStrategy(具体的策略)

负责实现Strategy的接口,即负责实现具体的策略

Context(上下文)

负责使用Strategy。Context保存了ConcreteStrategy的实例,并使用ConcreteStrategy去实现需求

示例

类图

策略模式示例类图

Hand

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class Hand {

public static final int HANDVALUE_GUO = 0;

public static final int HANDVALUE_CHO = 1;

public static final int HANDVALUE_PAA = 2;

private int handvalue;

public static final Hand[] hand = {
new Hand(HANDVALUE_GUO),
new Hand(HANDVALUE_CHO),
new Hand(HANDVALUE_PAA)
};

private static final String[] name = {"石头", "剪刀", "布"};

private Hand(int handvalue) {
this.handvalue = handvalue;
}

public static Hand getHand(int handvalue) {
return hand[handvalue];
}

public boolean isStrongerThan(Hand hand) {
return fight(hand) == 1;
}

public boolean isWeakerThan(Hand hand) {
return fight(hand) == -1;
}

private int fight(Hand hand) {
if (this == hand) {
return 0;
} else if ((this.handvalue + 1) % 3 == hand.handvalue) {
return 1;
} else {
return -1;
}
}

public String toString() {
return name[handvalue];
}

}

Strategy

1
2
3
4
public interface Strategy {
public abstract Hand nextHand();
public abstract void study(boolean win);
}

WinningStrategy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class WinningStrategy implements Strategy {

private Random random;

private boolean won = false;

private Hand privateHand;

public WinningStrategy(int seed) {
random = new Random(seed);
}

@Override
public Hand nextHand() {
if (!won) {
privateHand = Hand.getHand(random.nextInt(3));
}
return privateHand;
}

@Override
public void study(boolean win) {
won = win;
}

}

ProbStrategy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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) {
this.random = new Random(seed);
}

@Override
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 handValue) {
int sum = 0;
for (int i = 0;i < 3;i++) {
sum += history[handValue][i];
}
return sum;
}

@Override
public void study(boolean win) {
if (win) {
history[prevHandValue][currentHandValue]++;
} else {
history[prevHandValue][(currentHandValue + 1) % 3]++;
history[prevHandValue][(currentHandValue + 2) % 3]++;
}
}

}

Player

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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 ].";
}
}

Main

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Main {
public static void main(String[] args) {
if (2 != args.length) {
System.out.println("Usage: java Main randomseed1 randowseed2");
System.out.println("Example: java Main 315 15");
System.exit(0);
}

int seed1 = Integer.parseInt(args[0]);
int seed2 = Integer.parseInt(args[1]);

Player player1 = new Player("A", new WinningStrategy(seed1));
Player player2 = new Player("B", 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());
}
}

0%