zoukankan      html  css  js  c++  java
  • Strategy模式与Delegate委托

    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 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委托来实现扩展。个人意见,我还是倾向于第一种方案,但后者至少也提供了一种思路。尤有甚者,我们也可以将委托理解为一种特殊的抽象,因为其本质是函数指针,它代表了一簇函数,从而对具有相同特性的行为进行了普遍意义的抽象。也许,这样可以促进对委托的理解。

  • 相关阅读:
    理想团队模式构建的设想以及对软件流程的理解
    一、环境搭建 之 Windows10 安装 python3.5.2
    Codeforces1176A(A题)Divide it!
    Codeforces1144A(A题)Diverse Strings
    Codeforces1144B(B题)Parity Alternated Deletions
    Codeforces1144C(C题)Two Shuffled Sequences
    Codeforces1144D(D题)Equalize Them All
    Codeforces1157A(A题)Reachable Numbers
    Codeforces1157B(B题)Long Number
    Codeforces1141E(E题)Superhero Battle
  • 原文地址:https://www.cnblogs.com/wayfarer/p/210115.html
Copyright © 2011-2022 走看看