读书笔记--策略模式

来源:互联网 发布:windows nt 4.0补丁包 编辑:程序博客网 时间:2024/06/08 06:38

策略模式(Strategy):策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。封装变化点,是面向对象重要的一种很重要的思维。

简单工厂模式,虽然也能解决商场打折的问题,但是这个模式只是解决对象的创建问题,而且由于工厂本身包括了所有的收费方式,商场是可能经常性地更改打折额度和返利额度,每次维护或者扩展收费方式,都需要改动这个工厂,以致代码需要重新编译部署,面对算法的经常改动,可以应用策略模式。


Strategy类,定义所有支持的算法的公共接口

//抽象算法类

abstract class Strategy{

 //算法方法

public abstract void AlgorithmInterface();

}

//上下文

class Context{

 Strategy strategy;

public Context(Strategy strategy){

 this.strategy = strategy;

}

//上下文接口

public void ContextInterface(){

 strategy.AlgorithmInterface();

}

}


ConcreteStrategy,封装了具体的算法或行为,继承于Strategy

具体算法A

class ConcreteStrategyA extends Strategy{

//算法A实现方法

public void AlgorithmInterface(){

System.err.println("算法A实现");

}

}

//具体算法B

class ConcreteStrategyB extends Strategy{

 //算法B实现方法

public void AlgorithmInterface(){

System.err.println("算法B实现");

}

}

//具体算法C

class ConcreteStrategyC extends Strategy{

//算法C实现方法

public void AlgorithmInterface(){

System.err.println("算法C实现");

}

}

//客户端代码 主程序

public static void main( String [] args){

 Context context;

 context = new Context(new ConcreteStrategyA());

 context.ContextInterface();


context = new Context(new ConcreteStrategyB());

context.ContextInterface();


context = new Context(new ConcreteStrategyC());

context.ContextInterface();


}






//现金收费抽象类、策略类

abstract class CashSuper{

//现金收取超类的抽象方法,收取现金,参数为原价,返回为打折后价格

 public abstract double acceptCash(double money);

}

//正常收费子类

class CashNormal extends CashSuper{

public double acceptCash(double money){

 return money;

}

//打折收费子类

class CashRebate extends CashSuper{

 private double moneyRebate = 1d;

 public CahRebate(String moneyRebate){

 //打折收费,初始化时,必须要输入折扣率,如0.8,0.5

  this.moneyRebate = double.Parse(moneyRebate);

}

 public double acceptCash(double money){

 return money*moneyRebate;

}

}

//返利收费子类

class CashReturn extends CashSuper{

private double moneyCondition = 0.0d;

private double moneyReturn = 0.0d;

public CashReturn(String moneyConditon,String moneyReturn){

  this.moneyCondition = double.Parse(moneyCondition);

  this.moneyReturn = double.Parse(moneyReturn);

}

 public double acceptCash(double money){

  double result = money;

 if(money >= moneyCondition){

 result = money - Math.Floor(money / moneyCondition)*moneyReturn;

}

 return result;

}

}

//上下文类  策略与简单工厂结合,以免在主程序判断收费优惠

class CashContext{

 CashSuper cs = null;

//注意参数不是具体的收费策略对象,而是一个字符串,表示收费类型  

public CashContext(String type){

 switch (type)

{

 case "正常收费":

    CashNormal cs0 = new CashNormal();

    cs = cs0;

    break;

  case "满300返100":

        CashReturn cr1 = new CashReturn("300","100");

         cs = cr1;

         break;

 case "打8折":

   CashRebate cr2 = new CashRebate("0.8");

   cs = cr2;

   break;

}

}

  public double GetResult(double money)

 {

    return cs.acceptCash(money);

}

}


//客户端代码

double total = 0.0d;

private void btnOk_Click(object sender,EventArgs e)

{

 //根据选择,将相应的算法类型字符串传入CashContext的对象中

 CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());

 double totalPrices = 0d;

 totalPrices = csuper.GetResult(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.Text));

total = total + totalPrices;

List list = new ArrayList();

 list.add("单价:"+txtPrice.Text + "数量:"+txtNum.Text+""+cbxType.SelectItem+"合计:"+totalPrices.ToString());

 lblResult.Text = total.ToString();

}

//简单工厂模式的用法

CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());

... = csuper.GetResult(...)


//策略模式和简单工厂结合

CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());

... = csuper.GetResult(...);


简单工厂模式需要让客户端认识两个类,CashSuper和CashFactory,而策略模式与简单工厂结合的用法,客户端只需要认识一个类,CashContext,耦合性更低。

在客户端实例化的是CashContext的对象,调用的是CashContext的方法GetResult,这使得具体的收费算法,彻底与客户端分离


策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它们可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于提取出这些算法中的公共功能。另外一个优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

策略模式是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑用策略模式处理这种变化的可能性。

在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。这本身并没有解除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以有Context来承担,这就最大化地减轻了客户端的职责。


0 0
原创粉丝点击