[Design Patterns]StrategyPattern

策略模式屬於『行為型模式』,可以搭配簡單工廠模式一起使用。
與簡單工廠模式不同於,策略模式關注的是行為,簡單工廠關注的是物件。

目的

將達成一種目的中各種不同邏輯(策略),包裝為一個專門的類別。

角色

  • 抽象策略:一般為具體策略的父類別
  • 具體策略:繼承抽象產品
  • 策略介面:根據注入的策略實體,計算結果
  • 策略工廠介面:結合簡單工廠,注入策略類型,再根據策略產生實體,計算結果

優點

  • 靈活的替換不同的策略
  • 拓展容易
  • 減少if else

缺點

  • 要自行選擇策略
  • 會產生很多策略類

UML

UML

實際範例:收銀機

  • 抽象策略:CashSuper
1
2
3
4
public abstract class CashSuper
{
public abstract double AcceptCash(double money);
}
  • 具體策略:正常收費
1
2
3
4
5
6
7
public class CashNormal : CashSuper
{
public override double AcceptCash(double money)
{
return money;
}
}
  • 具體策略:滿300返100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class CashReturn : CashSuper
{
private double condition = 0.0d;
private double moneyReturn = 0.0d;

public CashReturn(string condition, string moneyReturn)
{
this.condition = double.Parse(condition);
this.moneyReturn = double.Parse(moneyReturn);
}

public override double AcceptCash(double money)
{
double result = money;

if (money >= condition)
{
result = money - Math.Floor(money / condition) * moneyReturn;
}

return result;
}
}
  • 具體策略:打8折
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class CashRebate : CashSuper
{
private double rebate = 1d;

public CashRebate(string rebate)
{
this.rebate = double.Parse(rebate);
}

public override double AcceptCash(double money)
{
return money * rebate;
}
}
  • 策略介面:注入折扣的策略實體,由使用者選擇策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class CashContext
{
private CashSuper cs;

public CashContext(CashSuper cs)
{
this.cs = cs;
}

public double GetResult(double money)
{
return cs.AcceptCash(money);
}
}
  • 策略工廠介面:注入折扣的類型,由工廠判斷產生哪種策略實體
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 CashContextFactory
{
private CashSuper cs = null;

public CashContextFactory(string type)
{
switch (type)
{
case "正常收費":
cs = new CashNormal();
break;
case "滿300返100":
cs = new CashReturn("300", "100");
break;
case "打8折":
cs = new CashRebate("0.8");
break;
default:
break;
}
}

public double GetResult(double money)
{
return cs.AcceptCash(money);
}
}

DEMO畫面

DEMO畫面

-------------The End-------------