一、概念
政策模式(strategy):它定義了一系列的算法,并将每一個算法封裝起來,而且使它們還可以互相替換。政策模式讓算法的變化不會影響到使用算法的客戶。(原文:the
strategy pattern defines a family of algorithms,encapsulates each one,and makes
them interchangeable. strategy lets the algorithm vary independently from
clients that use it.)

圖1 政策模式類圖
優點:
1、 簡化了單元測試,因為每個算法都有自己的類,可以通過自己的接口單獨測試。
2、
避免程式中使用多重條件轉移語句,使系統更靈活,并易于擴充。
3、
遵守大部分grasp原則和常用設計原則,高内聚、低偶合。
缺點:
1、
因為每個具體政策類都會産生一個新類,是以會增加系統需要維護的類的數量。
2、
在基本的政策模式中,選擇所用具體實作的職責由用戶端對象承擔,并轉給政策模式的context對象。(這本身沒有解除用戶端需要選擇判斷的壓力,而政策模式與簡單工廠模式結合後,選擇具體實作的職責也可以由context來承擔,這就最大化的減輕了用戶端的壓力。)
參考閱讀:
1. 2.
二、我的了解
其實這個政策模式和簡單工廠模式一樣,僅僅是對面向對象繼承中常用的override技術的一種應用。簡單工廠模式中有一個工廠類,負責根據輸入參數的不同來生成不同的子類,并将生成的子類作為基類傳回(這樣可以讓用戶端在使用的時候很友善)。用戶端隻需要調用工廠類建立一個基類的執行個體,然後調用這個執行個體的函數來實作自己的功能。而政策模式中的context類的功能基本上就是對工廠類的強化版本,它也負責根據輸入參數來生成不同的類,隻是它并不傳回生成類,而是将生成類所實作的功能接口包裝一次,提供給客戶。這樣對客戶來說,他們隻需要知道這一個context類就可以完成他們想要的功能,而不必再知道其他的資訊。
三、政策模式與簡單工廠模式結合的代碼實作
下面以一個簡單的商場收銀系統為例,示範一下政策模式與簡單工廠模式結合的使用。我将這個系統用兩個工程實作。一個工程實作商場計費的業務功能,另一個工程用于實作pos機上的界面,也就是用戶端。
首先介紹第一個工程:
1. 實作計費功能的基類(這裡用抽象類實作):
1 namespace colinsong.designpattern.strategy
2
{
3 public abstract class billingalgorithm
4
5 public abstract double getbillingresult(double price, int
quantity);
6 }
7 }
2. 實作具體計費功能的子類:
2.1 實作打折計費的子類:
3 public class billingstrategy_rebate:billingalgorithm
4 {
5 double discounts;
6 public
billingstrategy_rebate(double discounts)
7 {
8 if (discounts <
0.0000001 || discounts >= 1)
9
10 this.discounts =
1;
11
}
12
else
13
14 this.discounts =
discounts;
15
16 }
17
18 public
override double getbillingresult(double price, int
quantity)
19 {
20 return
price * quantity *
21
22 }
23 }
2.2 實作返現計費功能的子類:
3 public class billingstrategy_cashreturn:billingalgorithm
5 int cashcondition;
6 int cashreturn;
7
public billingstrategy_cashreturn(int cashcondition, int cashreturn)
8 {
9 if (cashcondition
<=
0)
10
11
cashcondition =
12
13 if (cashreturn <=
14
15
cashreturn =
16
17 this.cashcondition = cashcondition;
18 this.cashreturn =
cashreturn;
19 }
20
21
public override double getbillingresult(double price, int
22 {
23 double
orignal = price * quantity;
24 int n = (int) (orignal / cashcondition);
25
return orignal - cashreturn *
n;
26
27 }
28 }
29
3. context類
1
namespace
colinsong.designpattern.strategy
3
public class billing
4
5
//維護一個算法基類的執行個體
6
billingalgorithm billingalgorithm;
8
//簡單工廠模式的構造函數
9
public billing(string billingstrategy)
10
11
switch (billingstrategy)
13
case "打8折":
14
billingalgorithm = new billingstrategy_rebate(0.8);
15
break;
16
case "滿200返40":
billingalgorithm = new billingstrategy_cashreturn(200, 40);
18
19
default:
billingalgorithm = new billingstrategy_rebate(1);
22
23
24
//政策模式的構造函數
public billing(billingalgorithm billingalgorithm)
26
27
this.billingalgorithm = billingalgorithm;
28
//這是政策模式的典型特征
30
public double getresult(double price, int quantity)
31
32
return billingalgorithm.getbillingresult(price, quantity);
33
34
35
36
好,算法完成了,下面介紹用戶端,界面如圖2所示:
圖2. 商場收銀系統界面
下面看一下,确定按鈕後面的代碼:
code
over。o(∩_∩)o