Strategy模式是对算法的封装。即使是一个计算行为,如果其实现有其多样性,为达到易扩展的目的,我们也有必要将其抽象出来,以接口的形式来定义。由于充分利用了面向对象的多态性,在调用该行为时,其具体的实现是在运行期决定的。以税收计算为例,假定税收策略分为个人所得税,和企业所得税。根据策略模式,将税收策略抽象为接口ITaxStrategy:

public interface ITaxStrategy

{

double Calculate(double income);

}

各种税收策略均实现该类。

public class PeronalTaxStrategy:ITaxStrategy

{

public double Calculate(double income)

{

//实现;

}

}

public class EnterpriseTaxStrategy:ITaxStrategy

{

public double Calculate(double income)

{

//实现;

}

}

如果此时有一个公共的类,提供税收的相关操作,其中就包括计算所得税的方法:

public class TaxOp

{

private ITaxStrategy strategy;

public TaxOp(ITaxStrategy strategy)

{

this.strategy = strategy;

}

public double GetTax(double income)

{

return strategy.Calculate(income);

}

}

客户端调用:

public class App

{

public static void <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Main(string[] args)

{

TaxOp op = new TaxOp(new PersonalTaxStrategy());

Console.WriteLine(“The Personal Tax is :{0}”, op.GetTax(1000));

}

}

这是一种典型的面向对象的设计思路。然而,对于一些简单的算法行为,我们也可以利用delegate委托的方式,来实现以上的设计,它虽然更近似于面向过程的设计,但其扩展性同样灵活。如果算法的逻辑不复杂,且算法的实现处于某种待定的状态,也许使用委托会比Strategy模式更方便。

我们同样利用上述的例子,只是将原来抽象出来的接口修改为委托:

public delegate double CalculateTax(double income);

对于个人所得税和企业所得税的实现,相应修改为:

public class Tax

{

public static double CalculatePersonalTax(double income)

{

//实现;

}

public static double CalculateEnterpriseTax(double income)

{

//实现;

}

}

税收的公共类则修改如下:

public class TaxOp

{

private CalculateTax calDel;

public TaxOp(Calculate calDel)

{

this.calDel = calDel;

}

public double GetTax(double income)

{

return calDel(income);

}

}

客户端的调用:

public class App

{

public static void Main(string[] args)

{

TaxOp op = new TaxOp(new CalculateTax(Tax.CalculatePersonalTax));

Console.WriteLine(“The Personal Tax is :{0}”, op.GetTax(1000));

}

}

从这两个实现方案来看,代码是大同小异的,但设计思想则迥然不同。它是面向对象和面向过程的区别,前者是将行为封装为对象,而后者则直接对方法进行操作,同时又利用delegate委托来实现扩展。个人意见,我还是倾向于第一种方案,但后者至少也提供了一种思路。尤有甚者,我们也可以将委托理解为一种特殊的抽象,因为其本质是函数指针,它代表了一簇函数,从而对具有相同特性的行为进行了普遍意义的抽象。也许,这样可以促进对委托的理解。

Strategy模式与Delegate委托相关推荐

  1. 【C#学习】delegate(委托) 和 event(事件)

    C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针.委托(Delegate) 是存有对某个方法的引用的一种引用类型变量.引用可在运行时被改变.在C#中方法不能作为参数直接传递,必须 ...

  2. 设计模式学习笔记——策略(Strategy)模式

    设计模式学习笔记--策略(Strategy)模式 @(设计模式)[设计模式, 策略模式, Stategy] 设计模式学习笔记策略Strategy模式 基本介绍 策略案例 类图 实现代码 Hand类 S ...

  3. STRATEGY模式(冒泡算法为例)

    STRATEGY模式 STRATEGY模式使用了一种非常不同的方法来倒置通用算法和具体实现之间的依赖关系. 不是将通用的应用算法放进一个抽象基类中,而是将它放进一个名为BubbleSorter的具体类 ...

  4. 什么是委派模式(Delegate)?应用场景是什么?

    委派模式(Delegate),单从字面理解,就是项目经理叫程序猿去干活,这个就是委派模式,委派模式是这么定义的:类B和类A是两个互相没有任何关系的类,但是B具有和A一模一样的方法和属性:并且调用B中的 ...

  5. Strategy模式和Template Method模式的异同浅析

    一.Strategy模式 1. 特点说明: 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换. 适用场景: 许多相关的类仅仅是行为有异."策略"提供了一种用多个行为中的 ...

  6. 游戏开发设计模式之状态模式 有限状态机 c#委托事件(unity3d 示例实现)

    命令模式:游戏开发设计模式之命令模式(unity3d 示例实现) 对象池模式:游戏开发设计模式之对象池模式(unity3d 示例实现) 原型模式:游戏开发设计模式之原型模式 & unity3d ...

  7. 设计模式【14】——策略模式( Strategy 模式)

    文章目录 前言 一.策略模式( Strategy 模式) 二.具体源码 1.Strategy.h 2.Strategy.cpp 3.Context.h 4.Context.cpp 5.main.cpp ...

  8. 设计模式(四)【Strategy模式】

    Strategy模式 <设计模式>中的三个原则: 1.针对接口编程而不是实现 2.优先使用对象组合而不是类继承 3.考虑设计中哪些是可变的,对变化的概念进行封装. 例:国际电子商务系统案列 ...

  9. Strategy模式

    一.从订餐开始<?XML:NAMESPACE PREFIX = O /> 小王和小刘两人到餐厅点餐,两人分别如下告诉厨师. 小王:我要一杯加了香草冰淇淋的巧克力汽水. 小刘:一个黑与白. ...

最新文章

  1. 仿照redis写的nginx开机画面
  2. Python踩坑指南(第三季)
  3. 无法加载mcrypt扩展,请检查您的php配置的解决办法
  4. Cloud Native 介绍
  5. 【VSCode快捷键大合集】
  6. gpt efi win7 linux,科学网—UEFI+GPTSSD+HDD 成功安装win10+Centos linux7 过程 - 陈长云的博文...
  7. 二分--求最小值的最大p1m2
  8. 基于信息熵确立权重的topsis法_一种基于加权秩和比法的光伏并网逆变器多性能指标评价方法研究...
  9. 设计【SPFA】【差分约束】
  10. XCodeGhost
  11. Pyqt5 遇到的超级无敌大坑!clicked.connect后面的connect出现下划线 计算机积极拒绝问题
  12. nginx 502错误原因及解决办法
  13. VS中给qt按钮添加图标
  14. lua invalid pattern capture
  15. [青海、甘南之行散记] 当风吹过高原,一颗心在说话
  16. wxformbuilder软件制作gui界面教程
  17. 维基解密再爆猛料:CIA利用漏洞入侵全球数十亿个人电子设备
  18. 使用ssh 的ControlMaster实现不用每次ssh都输入密码
  19. 图像质量评价的方法和意义
  20. Google登录强制启用二次身份验证与FIDO解决方案

热门文章

  1. ZeroC ICE java异步实现方式(ami/amd)
  2. C语言:一个涉及指针函数返回值与printf乱码、内存堆栈的经典案例
  3. 编程语言java-并发(锁)
  4. 使用密钥验证方式登录linux系统
  5. Lua编译实践1-词法分析:
  6. NHibernate学习系列一
  7. 《LeetCode力扣练习》第617题 合并二叉树 Java
  8. sqlplus连mysql库_sqlplus连接服务器的Oracle的经历
  9. sqlserver 参数化查询 允许为null_1+Null 居然等于 Null
  10. linux系统reboot怎么退出,Linux系统肿么退出?