# 深入浅出设计模式——策略模式（Strategy Pattern）

Strategy Pattern: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Frequency of use: medium high
UML图

Context: 环境类
Strategy: 抽象策略类
ConcreteStrategy: 具体策略类

Context: 环境类 CashContext.cs

namespace StrategyPattern
{
class CashContext
{
private CashSuper cs;

//通过构造方法，传入具体的收费策略
public CashContext(string type)
{
switch (type)
{
case "正常收费":
CashNormal cs0 = new CashNormal();
cs = cs0;
break;
case "满300返100":
CashReturn cs1 = new CashReturn("300", "100");
cs = cs1;
break;
case "打八折":
CashRebate cs2 = new CashRebate("0.8");
cs = cs2;
break;
}
}
public double GetResult(double money)
{
//根据收费策略的不同，获得计算结果
return cs.acceptCash(money);
}
}
}

Strategy: 抽象策略类 CashSuper.cs

namespace StrategyPattern
{
//现金收费抽象类
abstract class CashSuper
{
public abstract double acceptCash(double money);
}
}

ConcreteStrategy: 具体策略类 CashNormal.cs

namespace StrategyPattern
{
//正常收费子类
class CashNormal : CashSuper
{
public override double acceptCash(double money)
{
return money;
}
}
}

CashRebate.cs

namespace StrategyPattern
{
//打折收费子类
class CashRebate : CashSuper
{
private double moneyRebate = 1d;
public CashRebate(string moneyRebate)
{
this.moneyRebate = double.Parse(moneyRebate);
}
public override double acceptCash(double money)
{
return money * moneyRebate;
}
}
}

CashReturn.cs

using System;

namespace StrategyPattern
{
//返利收费子类
class CashReturn : CashSuper
{
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(string moneyCondition, string moneyReturn)
{
this.moneyCondition = double.Parse(moneyCondition);
this.moneyReturn = double.Parse(moneyReturn);
}
public override double acceptCash(double money)
{
double result = money;
if (money >= moneyCondition)
result = money - Math.Floor(money / moneyCondition) * moneyReturn;
return result;
}
}
}

Client：客户类

using System;
using System.Windows.Forms;

namespace StrategyPattern
{
public partial class Form1 : Form
{
//声明一个double变量total来计算总计
double total = 0.0d;

public Form1()
{
InitializeComponent();
}

private void btnOk_Click(object sender, EventArgs e)
{
CashContext cc = new CashContext(cbxType.SelectedItem.ToString());

double totalPrices = 0d; ;
totalPrices = cc.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));

//将每个商品合计计入总计
total = total + totalPrices;

lbxList.Items.Add("单价：" + txtPrice.Text + "数量：" + txtNum.Text + " 合计：" + totalPrices.ToString());
lblResult.Text = total.ToString();
}

private void Form1_Load(object sender, EventArgs e)
{
cbxType.Items.AddRange(new object[] { "正常收费", "满300返100", "打八折" });
cbxType.SelectedIndex = 0;
}
}
}

 策略模式提供了对“开闭原则”的完美支持，用户可以在不修改原有系统的基础上选择算法或行为，也可以灵活地增加新的算法或行为。
 策略模式提供了管理相关的算法族的办法。
 策略模式提供了可以替换继承关系的办法。
 使用策略模式可以避免使用多重条件转移语句。

 客户端必须知道所有的策略类，并自行决定使用哪一个策略类。
 策略模式将造成产生很多策略类，可以通过使用享元模式在一定程度上减少对象的数量。

 如果在一个系统里面有许多类，它们之间的区别仅在于它们的行为，那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
 一个系统需要动态地在几种算法中选择一种。
 如果一个对象有很多的行为，如果不用恰当的模式，这些行为就只好使用多重的条件选择语句来实现。
 不希望客户端知道复杂的、与算法相关的数据结构，在具体策略类中封装算法和相关的数据结构，提高算法的保密性与安全性。

【声明与感谢】

【参考文献】
《设计模式—可复用面向对象软件的基础》作者: [美] Erich Gamma / Richard Helm / Ralph Johnson / John Vlissides 译者: 李英军 / 马晓星 / 蔡敏 / 刘建中 等 机械工业出版社
《重构—改善既有代码的设计》作者: Martin Fowler译者：候捷 中国电力出版社
《敏捷软件开发—原则、模式与实践》作者: Robert C. Martin 清华大学出版社
《程序员修炼之道—从小工到专家》作者: Andrew Hunt / David Thomas 电子工业出版社
《Head First 设计模式》作者: 弗里曼 译者: O'Reilly Taiwan公司 中国电力出版社
《设计模式之禅》 作者: 秦小波 机械工业出版社
MSDN WebCast 《C#面向对象设计模式纵横谈》 讲师：李建忠

《大话设计模式》 作者: 程杰 清华大学出版社
《C#图解教程》作者: 索利斯 译者: 苏林 / 朱晔 人民邮电出版社
《你必须知道的.NET》作者: 王涛
《项目中的.NET》作者: 李天平 电子工业出版社
《Microsoft .NET企业级应用架构设计》作者: （美）埃斯波西托等编著 译者: 陈黎夫
http://www.dofactory.com/Patterns/Patterns.aspx .NET Design Patterns
http://www.cnblogs.com/zhenyulu 博客作者：吕震宇
http://www.cnblogs.com/terrylee 博客作者：李会军
http://www.cnblogs.com/anlyren/ 博客作者：anlyren
http://www.cnblogs.com/idior 博客作者：idior
http://www.cnblogs.com/allenlooplee 博客作者：Allen lee
http://blog.csdn.net/ai92 博客作者：ai92
http://www.cnblogs.com/umlonline/ 博客作者：张传波
http://www.cnblogs.com/lovecherry/ 博客作者：LoveCherry

posted @ 2015-01-04 11:38  Bobby0322  阅读(...)  评论(... 编辑 收藏