策略模式定義:分別封裝行爲接口,實現算法族,超類裏放行爲接口的對象,在子類裏具體設定行爲對象。原則就是,分離變化部分,封裝接口,基於接口編程各種功能。此模式讓行爲算法的變化獨立於算法的使用者。
策略模式注意點:
-
分析項目中的變化部分與不變部分
-
多用組合少用繼承;用行爲類組合,而不是行爲的繼承。更有彈性
案例1:
在三國殺裏面,我們每個玩家都是一個獨立的對象。有時候我們會抽到一些武器卡,每個對象只能持有一個武器。對於這種情況我們及時沒有策略模式的概念,也會很自然的想到以下方案
1
2
3
4
5
|
public interface weapon
{ public void attack(Player
victim); } |
1
2
3
4
5
6
7
8
9
10
11
|
//武器:流星錘 public class MeteorHammer implements weapon
{ private final byte power
= 2 ; private final byte distance
= 3 ; @Override public void attack(Player
victim) { victim.beAttacked(power); } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class Player
{ private weapon
weapon; //生命值 private byte hitpoints; //每個玩家的位置,等於在房間類中,玩家在ArrayList<Player>中的Index private byte position; public void attackPlayer(Player
victim){ /* *
1.首先檢查距離是否可以攻擊 *
2.距離允許,則攻擊 weapon.attack() */ } public void beAttacked( byte power){ this .hitpoints
-= power; } } |
案例2:在HttpClient中,HttpClient提供了很多種瀏覽器策略,但是用戶具體實例化瀏覽器對象時,瀏覽器採取何種策略,由用戶自己選擇。這種也是採用策略模式的思想,提取變化部分,抽象成接口,在實現其各種子類,再動態稱爲瀏覽器對象的字段
1
2
3
4
|
LaxRedirectStrategy
laxRedirectStrategy = new LaxRedirectStrategy(); CloseableHttpClient
httpClient = HttpClients.custom() .setRedirectStrategy(laxRedirectStrategy) .build(); |