标签:style blog http io color ar os 使用 sp
引入问题:要实现一个商场收费软件,根据单价,数量来向客户收费,其中收费方式可以有多种(变化多)。
方法一:简单工厂模式实现
一个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封装了具体算法行为,继承于Strategy class 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();
用策略与简单工厂结合改造,把客户端判断的过程转移实现隐藏:
标签:style blog http io color ar os 使用 sp
原文地址:http://www.cnblogs.com/rat-bin/p/4101447.html