首页 > 代码库 > 策略模式
策略模式
引入问题:要实现一个商场收费软件,根据单价,数量来向客户收费,其中收费方式可以有多种(变化多)。
方法一:简单工厂模式实现
一个CashSuper类统一接口,多个具体的计算类继承于CashSuper类,一个工厂方法CashFactory创建具体实现类。
//现金收费抽象类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 moneyRebate*money; }}//返利收费class CashReturn:CashSuper{ private double moneyCondition = 0.0d; private double moneyReturn = 0,0d; public CashReturn(String moneyCondition,String moneyReturn) { this.moneyReturn = double.Parse(moneyReturn); this.moneyCondition = double.Parse(moneyCondition); } public override double acceptCash(double money) { double res = money; if(money >= moneyCondition){ res = money - Math.Floor(money/moneyCondition)*moneyReturn; } return res; }}//工厂类class CashFactory{ public static CashSuper createCashAccept(String type) { CashSuper cs = null; switch(type) { case "正常收费": cs = new CashNormal(); break; case "八折": CashRebate cr1== new CashRebate("0.8") cs = cr1; break; case "满三百送一百": CashReturn cr2 = new CashReturn("300","100") cs = cr2; break; } return cs; }}
此时要想增加一个积分算法,如满一百积分10分,积分可兑换礼品,则加一个积分算法,传两参数(条件,返点),让它继承CashSuper,在到收费对象生成的工厂添加分支即可。
以上虽然实现了,但是商场经常性地更改打折额度和返利额度,每次维护都要改动这个工厂导致代码要重新编译部署,所以解决面对算法会时常变动的情况下,策略模式就出来解决了这个问题。
策略模式:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。(封装变化点)
context上下文,用一个ConcreteStrategy来配置维护一个对Strategy对象的引用。
//抽象算法类,定义了所以支持算法的公共接口abstract class Strategy{ public abstract void AlgorithmInterface();}//ContreteStrategy封装了具体算法行为,继承于Strategyclass ContreteStrategyA : Strategy{ public override void AlgorithmInterface() { Console.WriteLine("A实现") }}class ContreteStrategyB : Strategy{ public override void AlgorithmInterface() { Console.WriteLine("B实现") }}class ContreteStrategyC : Strategy{ public override void AlgorithmInterface() { Console.WriteLine("C实现") }}//Context,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用class Context{ Strategy st; public Context(Strategy st) { this.st = st; } //接口 public void ContextInterface() { Strategy.AlgorithmInterface(); }}//客户端static void Main(string[] args){ Context context; context = new Context(new ContreteStrategyA()); context.ContextInterface(); Context context; context = new Context(new ContreteStrategyB()); context.ContextInterface(); Context context; context = new Context(new ContreteStrategyC()); context.ContextInterface(); Console.Read();}
方法二:
只需在方法一中加一个CashContext类并改写客户端代码就行:
class CashContext{ private CashSuper cs; public CashContext(CashSuper cs) { this.cs = cs; } public double GetResult(double money) { return cs.acceptCash(money); }}
CashContext cs = null;switch(type){ case "正常收费": cs = new CashContext(new CashNormal()); break; case "": . . .}double res = cs.GetResult();
用策略与简单工厂结合改造,把客户端判断的过程转移实现隐藏:
策略模式
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。