1.什么是策略模式
就是定义一组算法,把每个算法给封装起来,它们之间可以相互调用,并且它们之间可以相互交换; 此模式让算法发生变化,不会影响使用算法的客户。
* 策略模式的核心就是对算法的包装,最终目的是把使用算法的责任(环境)和算法的实现进行耦合。
2.策略模式的优缺点:
(1)优点
- 算法可以自由的进行的切换
- 避免多重条件的判断(减少对象的数量),减少了程序代码的复杂性和冗余度。
- 扩展性非常好
- 策略类提供给了可以替换继承关系的办法
- 通过接口和
(2)缺点
- 策略类的数量增多比较繁琐。
- 所有策略类都需要对外暴露,暴露的越多,以后修改风险就越大,就是客户端必须知道所有的策略了,并且意味着用户必须理解这些每个算法的区别,选择合适的策略和方法。(可以使用享元模式来减少对象的数量)。
3.策略模式的实现方式
* 环境(Context)角色,持有一个,并且维护Strategy对象的引用,并决定调用那种Strategy角色完成业务逻辑。
* 抽象策略(Strategy)定义了所有支持算法的公共接口,是策略模式的核心,算法的归纳,是一个一致对外的接口。
* 具体策略(ConcreteStrategy)封装了具体的算法或行为,继承Strategy
4.策略模式的具体操作
(拿一个商场收银系统作为例子)
double total = 0.0d; //total来计算总计
private void BtnOk_Click(object sender, EventArgs e)
{
double totaprices = Convert.ToDouble(txtPrice.Text) *
Convert.ToDouble(txtNum.Text); //购买商品总价
//把商品价钱计入总计。
total = total + totaprices;
//列表框中显示信息。
lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text+"合计:" +
totaprices.ToString());
}
但是如果这样子去写的话,如果商场要增加打折的那该怎么办?
简单工厂模式实现:
我们先写一个正常收费的父类,然后再继承它实现多个打折和返利的子类,利用多态的方法去完成这个代码。
* CashSuper : 父类
* CashNormal : 没有折扣
* CashRebate : 打折
* CashReturn : 返利
有了这个简单的工厂模式,三个封装好的子类就能随意的去切换,(都在继承父类CashSuper)前提下。
//现金收费抽象类
abstract class Cashsuper
{
public abstract double AcceptCash(double money);
}
class CashNormal : Cashsuper //正常收费子类
{
public override double AcceptCash(double money) //正常收费,原价返回
{
return money;
}
}
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;
}
}
//返利类
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;
}
}
//现金收费工厂
class CashFactory
{
public static Cashsuper createCashAccept(string type)
{
Cashsuper cs = null;
switch (type)
{
case "正常收费":
cs = new CashNormal();
break;
case "满300返100":
CashReturn cr1 = new CashReturn("300", "100");
cs = cr1;
break;
case "打八折":
CashRebate cr2 = new CashReturn("0.8");
cs = cr2;
break;
}
return cs;
//客户端代码
double total = 0.0d; //total来计算总计
private void btnOk_Click(object sender, EventArgs e)
{
Cashsuper csuper = new CashContext(cbxType.SelectedItem.Tostring());
CashFactory.createCashAccept(cpxtype.SelectedItem.ToString());
double totalPrices = 0d;
totalPrices = csuper.AcceptCash(Convert.ToDouble(txtPrice.Text)) *
Convert.ToDouble(txtNum.Text);
total = total + totalPrices;
lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + "" +
cbxtype.selectedItem + "合计:" + totalPrices.ToString());
lblresult.Text = total.ToString();
}
策略模式与简单工厂的结合:
//客户端代码
double total = 0.0d; //total来计算总计
private void btnOk_Click(object sender, EventArgs e)
{
Cashsuper csuper = new CashContext(cbxType.SelectedItem.Tostring());
CashFactory.createCashAccept(cpxtype.SelectedItem.ToString());
double totalPrices = 0d;
totalPrices = csuper.AcceptCash(Convert.ToDouble(txtPrice.Text)) *
Convert.ToDouble(txtNum.Text);
total = total + totalPrices;
lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + "" +
cbxtype.selectedItem + "合计:" + totalPrices.ToString());
lblresult.Text = total.ToString();
}