ヘッドファーストデザインパターンのStrategyパターン

オリジナルリンク: http://www.cnblogs.com/xcsn/p/6906533.html

  これは、オンライン記事の要約を参照し、学ぶための最初のデザインパターン、および比較的複雑な例を書かれた本であります

まず、定義

   戦略モード(戦略パターン):彼らはお互いを置き換えることができるようにアルゴリズムの家族の定義は、このモードでは、アルゴリズムは、アルゴリズムを使用して、クライアントから独立して変化することができます、閉鎖されました。

   ポリシーモデルは、アルゴリズムのセットである彼らはお互いを置き換えることができるように、各アルゴリズムは、共通のインタフェースを持っている別のクラスにカプセル化されます。ポリシーモードの変更は、アルゴリズムは、クライアントの状況に影響を与えることができないことができます。

設計原理

  アプリケーションは、場所の変更を必要と識別し、独立したそれらを置く、および混合それらのコードを変更する必要はありません

デザイン原理II

  インタフェースのプログラミングではなく、プログラミングのための

デザイン原理III

  多目的組み合わせ、以下の継承

 

第二に、構造

戦略モードアルゴリズムのパッケージであり、およびアルゴリズムは、異なるオブジェクトに責任を委任自体が分割アルゴリズムを使用しての責任です。Strategyパターンは、通常、一連のアルゴリズムは、内部のような戦略のシリーズをパッケージ化します。文は、ポリシーモデルは寛大で含まれています - 「彼らは互換性がありますように、各アルゴリズムは、異なるクラスポリシーにカプセル化されました」

以下は、戦略パターンのブロック図です。

モデルは、3つの文字が含まれます。

  • 環境役割(コンテキスト):クラスの戦略への参照を保持しています
  • 抽象的な政策の役割(戦略):これは、通常、インターフェースや抽象クラスによって実装、抽象的役割です。この役割は、特定のポリシークラスを達成するために必要なすべてのインターフェイスを提供します。
  • 具体的な政策の役割(ConcreteStrategy):関連するアルゴリズムや振る舞いをパッケージ化。

第三に、達成するために

個人所得税を計算するために、以下のケーススタディ

namespace StrategyPattern
{
    // 所得税计算策略
    public interface ITaxStragety
    {
        double CalculateTax(double income);
    }
 
    // 个人所得税
    public class PersonalTaxStrategy : ITaxStragety
    {
        public double CalculateTax(double income)
        {
            return income * 0.12;
        }
    }
 
    // 企业所得税
    public class EnterpriseTaxStrategy : ITaxStragety
    {
        public double CalculateTax(double income)
        {
            return (income - 3500) > 0 ? (income - 3500) * 0.045 : 0.0;
        }
    }
 
    public class InterestOperation
    {
        private ITaxStragety m_strategy;
        public InterestOperation(ITaxStragety strategy)
        {
            this.m_strategy = strategy;
        }
 
        public double GetTax(double income)
        {
            return m_strategy.CalculateTax(income);
        }
    }
 
    class App
    {
        static void Main(string[] args)
        {
            // 个人所得税方式
            InterestOperation operation = new InterestOperation(new PersonalTaxStrategy());
            Console.WriteLine("个人支付的税为:{0}", operation.GetTax(5000.00));
 
            // 企业所得税
            operation = new InterestOperation(new EnterpriseTaxStrategy());
            Console.WriteLine("企业支付的税为:{0}", operation.GetTax(50000.00));
 
            Console.Read();
        }
    }
}

 关于其他例子

  •   被测试网站是一个针对全球很多市场的一个网站,有时同一个测试点,需要我们配置一下网络代理和其它不同的设置来模拟当地市场。

    http://www.cnblogs.com/heqichang/archive/2012/12/13/2815927.html

  

四、适用场景

  在.NET Framework中也不乏策略模式的应用例子。例如,在.NET中,为集合类型ArrayList和List<T>提供的排序功能,其中实现就利用了策略模式,定义了IComparer接口来对比较算法进行封装,实现IComparer接口的类可以是顺序,或逆序地比较两个对象的大小,具体.NET中的实现可以使用反编译工具查看List<T>.Sort(IComparer<T>)的实现。其中List<T>就是承担着环境角色,而IComparer<T>接口承担着抽象策略角色,具体的策略角色就是实现了IComparer<T>接口的类,List<T>类本身实现了存在实现了该接口的类,我们可以自定义继承与该接口的具体策略类。

在下面的情况下可以考虑使用策略模式:

  • 一个系统需要动态地在几种算法中选择一种的情况下。那么这些算法可以包装到一个个具体的算法类里面,并为这些具体的算法类提供一个统一的接口。
  • 如果一个对象有很多的行为,如果不使用合适的模式,这些行为就只好使用多重的if-else语句来实现,此时,可以使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,并体现面向对象涉及的概念。

 

 

五、优缺点

模式优点

  • 策略类之间可以自由切换。由于策略类都实现同一个接口,所以使它们之间可以自由切换。
  • 易于扩展。增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码。
  • 避免使用多重条件选择语句,充分体现面向对象设计思想。

模式缺点

  •  客户端必须知道所有的策略类,并自行决定使用哪一个策略类。

   这点可以考虑使用IOC容器和依赖注入的方式来解决,关于IOC容器和依赖注入(Dependency Inject)的文章可以参考:IoC 容器和Dependency Injection 模式

  •  策略模式会造成很多的策略类。

 

 

欢迎阅读本系列文章:Head First设计模式之目录

  

转载于:https://www.cnblogs.com/xcsn/p/6906533.html

おすすめ

転載: blog.csdn.net/weixin_30648587/article/details/94793591