策略模式(Strategy Pattern)
来源:互联网 发布:gta5女性捏脸数据 编辑:程序博客网 时间:2024/05/17 22:31
策略模式(Strategy Pattern)
策略模式定义了一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。别名:Policy(方针)
结构:
代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy{ abstract class Strategy { public abstract void AlgorithmInterface(); } class ConcreteStrategyA : Strategy { public override void AlgorithmInterface() { Console.WriteLine("Algorithm A implementation"); } } class ConcreteStrategyB : Strategy { public override void AlgorithmInterface() { Console.WriteLine("Algorithm B implementation"); } } class ConcreteStrategyC : Strategy { public override void AlgorithmInterface() { Console.WriteLine("Algorithm C implementation"); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy{ class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void ContextInterface() { strategy.AlgorithmInterface(); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy{ class Program { 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(); Console.ReadKey(); } }}参与者:
Strategy( 策略 )
— 定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
• ConcreteStrategy(具体策略)
— 以Strategy接口实现某具体算法。
• Context(上下文)
— 用一个ConcreteStrategy对象来配置。
— 维护一个对Strategy对象的引用。
— 可定义一个接口来让Strategy访问它的数据。
效果:
1)相关算法系列Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
2) 一个替代继承的方法。继承提供了另一种支持多种算法或行为的方法。你可以直接生成一个Context类的子类,从而给它以不同的行为。但这会将行为硬行编制到 Context中,而将算法的实现与Context的实现混合起来 , 从而使Context难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后你得到一堆相关的类 , 它们之间的唯一差别是它们所使用的算法或行为。将算法封装在独立的Strategy类中使得你可以独立于其Context改变它,使它易于切换、易于理解、易于扩展。
3) 消除了一些条件语句。Strategy模式提供了用条件语句选择所需的行为以外的另一种选择。当不同的行为堆砌在一个类中时 , 很难避免使用条件语句来选择合适的行为。将行为封装在一个个独立的Strategy类中消除了这些条件语句。
实现:
1)定义Strategy和Context接口
一种办法是让Context将数据放在参数中传递给Strategy操作——也就是说, 将数据发送给Strategy。这使得Strategy和Context解耦。另一种办法是让Context将自身作为一个参数传递给Strategy, 该Strategy再显式地向该Context请求数据。或者,Strategy可以存储对它的Context的一个引用, 这样根本不再需要传递任何东西。
2)将Strategy作为模板参数
template <class AStrategy>class Context {public void Operation() { theStrategy.DoAlgorithm(); }private: AStrategy theStrategy;}class MyStrategy{public: void DoAlgorithm();}Context<MyStrategy> myContext;可以在编译时选择Strategy,不需要在运行时改变,提高效率。
3)使Strategy对象称为可选
实际应用代码:
商场购物结账,根据不同的付账方式,选择不同的计算策略。CashContext用到了简单工厂,下面代码中策略模式与简单工厂相结合,降低了代码的耦合性。
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy1{ 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; } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy1{ 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); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MyStrategy1{ class Program { static void Main(string[] args) { double totalPrices = 100d; string cashType = "打8折"; CashContext csuper = new CashContext(cashType); totalPrices = csuper.GetResult(totalPrices); Console.ReadKey(); } }}
参考《设计模式》、《大话设计模式》,进行整理。
0 0
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- Strategy Pattern(策略模式)
- 策略(Strategy Pattern)模式
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式 (Strategy Pattern)
- 策略模式(Strategy Pattern)
- 策略模式(Strategy Pattern)
- 简单的封装与继承实例
- 致橡树--舒婷
- Objective-c 循环引用
- Java复习
- 1005. 继续(3n+1)猜想 (25)
- 策略模式(Strategy Pattern)
- 当数组作为函数参数时函数中sizeof()的讨论
- js进行前端数据的验证
- 深入浅出聊Unity3D项目优化:从Draw Calls到GC
- LeetCode(53) Maximum Subarray
- java.xml
- Java Web乱码问题
- Wait和Pulse
- 梯度下降