一前言
把自己学习的结果用文章表现出来并留做日后参考~今天要学习的模式为"策略模式"!
设计模式你怎么看?--简单工厂模式
设计模式你怎么看?--抽象工厂模式
设计模式你怎么看?--工厂方法模式
二 策略模式介绍
2.1 什么是策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
2.2 策略模式包含角色
—抽象策略角色(strategy): 策略类,通常由一个接口或者抽象类实现。
—具体策略角色(ConcreteStrategy):包装了相关的算法和行为。
—环境角色(Context):持有一个策略类的引用,最终给客户端调用
2.3 策略模式UML图
Strategy为抽象类或接口 定义算法方法,然后由ConcreteStategyA来实现具体的算法,而Context维护着Strategy的实例根据客户端来决定调用哪个子类的方法。
三 策略模式代码
抽象策略类定义公共的方法
/// <summary> /// 抽象策略类 /// 此抽象类提供统一接口或抽象方法 /// </summary> abstract class Strategy { public abstract void PrintName(); }
具体算法类也可以说是 具体策略类 主要是对算法的具体实现
/// <summary> /// 具体算法实现类 /// </summary> class ConcreteStrategyA:Strategy { public override void PrintName() { Console.WriteLine("这是具体策略类A"); } } class ConcreteStrategyB:Strategy { public override void PrintName() { Console.WriteLine("这是具体策略类B"); } } class ConcreteStrategyC:Strategy { public override void PrintName() { Console.WriteLine("这是具体策略类C"); } }
Context类维护一个Strategy的实例与Strategy之间交互和数据传递
/// <summary> /// Context 对象 维护对Strategy对象的引用 /// </summary> class StrategyContent { private Strategy _strategy; public StrategyContent(Strategy strategy) { this._strategy = strategy; } public void PrintStrategryMethod() { _strategy.PrintName(); } }
客户端类
/// <summary> /// Client /// </summary> class Program { static void Main(string[] args) { //将具体类的实例传入Context中 StrategyContent a = new StrategyContent(new ConcreteStrategyA()); StrategyContent b = new StrategyContent(new ConcreteStrategyB()); StrategyContent c = new StrategyContent(new ConcreteStrategyC()); a.PrintStrategryMethod(); b.PrintStrategryMethod(); c.PrintStrategryMethod(); Console.Read(); } }
结果如下:
进一步优化
策略模式写完后会发现,判断用哪个实例的逻辑又回到客户端去了,对于变化我们提倡要进行封装,那怎么处理呢 答案就是 把简单工厂与策略模式结合
只要修改如下两个类即可
1 Context类 注释部分为原来写法
/// <summary> /// Context 对象 维护对Strategy对象的引用 /// </summary> class StrategyContent { Strategy _strategy; //public StrategyContent(Strategy strategy) //{ // this._strategy = strategy; //} //用工厂模式处理 public StrategyContent(string type) { switch (type) { case "A": _strategy = new ConcreteStrategyA(); break; case "B": _strategy = new ConcreteStrategyB(); break; case "C": _strategy = new ConcreteStrategyC(); break; } } public void PrintStrategryMethod() { _strategy.PrintName(); } }
2 客户端类 用了简单工厂后已经把判断的逻辑封装到了工厂类中,所以客户端中不再有判断的逻辑, 也就符合了面向对象中的 封装变化 特征。
/// <summary> /// Client /// </summary> class Program { static void Main(string[] args) { //将具体类的实例传入Context中 //StrategyContent a = new StrategyContent(new ConcreteStrategyA()); //StrategyContent b = new StrategyContent(new ConcreteStrategyB()); //StrategyContent c = new StrategyContent(new ConcreteStrategyC()); //a.PrintStrategryMethod(); //b.PrintStrategryMethod(); //c.PrintStrategryMethod(); Console.Write("输入A,B,C "); string result = Console.ReadLine(); StrategyContent instance = new StrategyContent(result); instance.PrintStrategryMethod(); Console.Read(); } }
结果如下
四 总结
设计模式 先熟悉 再熟练 最后灵活运用!
"代码虽易,写好不易 且写且珍惜"
本人水平有限,如有不对之处还请指出 谢谢~
如果您觉得本文有给您带来一点收获,不妨点个推荐,为我的付出支持一下,谢谢~
如果希望在技术的道路上能有更多的朋友,那就关注下我吧,让我们一起在技术的路上奔跑