zoukankan      html  css  js  c++  java
  • 设计模式 笔记 策略模式 Strategy



    //---------------------------15/04/28----------------------------


    //Strategy 策略模式----对象行为型模式


    /*

        1:意图:

            定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。使算法可独立于使用它的客户而变化。

        2:别名:

            政策(Policy)

        3:动机:

        4:适用性:

            1>许多相关的类仅仅是行为有异。策略提供了一种用多个行为中的一个行为来配置一个类的方法。

            2>需要使用一个算法的不同变体。

            3>算法使用客户不应该知道的数据。使用策略模式可以避免暴露复杂的与算法相关的数据结构。

            4>一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。

              将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

        5:结构:

                Context:

                strategy--------------------------->Strategy:

                ContextInterface()                  AlgorithmInterface()

                                                        |

                                                ---------------------

                                                |                   |

                                        ConcteStrategyA:        ConcreteStrategyB:

                                        AlgorithmInterface()    AlgorithmInterface()

        6:参与者:

            1>Strategy

                定义所有支持的算法的公共接口。Context使用这个接口来调用某ConcreteStrategy定义的算法。

            2>ConcreteStrategy

                根据Strategy定义的接口实现具体算法

            3>Context

                1)用一个ConcreteStrategy对象来配置。

                2)维护一个对Strategy对象的引用。

                3)可定义一个接口来让Strategy访问它的数据。

        7:协作:

            1>StrategyContext相互作用以实现选定的算法,当算法被调用时,Context可以将该算法所需要的所有

              数据都传递给该Strategy。或者使用自身来当作参数传给Strategy

            2>Context将它的客户的请求转发给它的Strategy。客户通常创建并传递一个ConcreteStrategy对象给

              Context;这样客户可以仅与Context交互。

        8:效果:

            1>相关算法系列:

                Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法的公共功能

            2>一个替代继承的方法:

                如果使用继承来实现不同的算法,会导致Context难以理解,难以维护和难以扩展,并且算法和实现耦合很

                深,所以Strategy模式很好的补足了这些部分。

            3>消除了一些条件语句:

            4>实现的选择:

                Strategy可以提供相同行为的不同实现,客户可以根据不同时间/空间权衡取舍要求,从而选区不同的策略。

            5>客户必须了解不同的Strategy

                这是Strategy模式潜在的一个缺点,客户必须熟知Strategy的实现才能正确选择什么Strategy

            6>StrategyContext的通信开销:

                一些简单的Strategy可能不需要参数,但是为了别的Strategy考虑,ContextStrategy之间

                通信的接口必须要通用,也就是考虑到所有的参数,所以这可能造成浪费。

            7>增加了对象的数目:

                Strategy增加了应用中的对象的数目。可采用Flyweight来减少开销。

        9:实现:

            1>定义StrategyContext接口:

                1)传递一些数据:

                    Context可能会发送一些Strategy不需要的数据。这个方法通过加大开销来解耦两个类

                2)传递自己,或在Strategy中存放一个Context的引用:

                    这样StrategyContext会更紧密地耦合在一起。

            2>Strategy作为模版参数:

                这样必须满足两点:

                1)可以在编译时选择Strategy

                2)不需要在运行时改变

                这就是属于编译器多态。

            3>使Strategy对象称为可选的:

                如果即使不使用Strategy对象Context还是有意义的话,可以简化Context,让Context在访问Strategy

                前检查是否存在,有就使用,没有就执行缺省的行为。

        10:代码示例:                                                                        */



    //Context 里面保存了一个Compositior类的指针,也就是一个ConcreteStrategy

    class Composition

    {

    public:

        Composition(Compositior*);

        void Repair();

    private:

        Compositior* _compositor;

        Component* _components;

        int _componentCount;

        int _lineWidth;

        int* _lineBreaks;

        int _lineCount;

    };


    //Abstract Strategy

    class Compositor

    {

    public:

        virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

                            int componentCount, int lineWidth, int breaks[])=0;

    protected:

        compositor();

    };


    //这里使用到了Strategy的操作,Compose()

    void Composition::Repair()

    {

        Coord* natural;

        Coord* stretchability;

        Coord* shrinkability;

        int componentCount;

        int* breaks;

        

        int breakCount;

        breakCount = _compositor->Compose(natural, stretchability, shrinkability

                                          componentCount, _lineWidth, breaks);

        

    }


    //ConcreteStrategy:自己实现自己的Compose具体怎么做

    class SimpleCompositor : Compositor

    {

    public:

        SimpleCompositor();

        virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

                            int componentCount, int lineWidth, int breaks[]);

    };


    class TexCompositor : Compositor

    {

        TexCompositor();

        virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

                            int componentCount, int lineWidth, int breaks[]);

    };


    class ArrayCompositor : Compositor

    {

        ArrayCompositor(int interval);

        virtual int Compose(Coord natural[],Coord stretch[], Coord shrink[],

                            int componentCount, int lineWidth, int breaks[]);

    };


    //简单的使用,但是每次都要new一个Strategy对象,可以使用Flyweight模式优化

    Composition* quick = new Composition(new SimpleCompositor);

    Composition* slick = new Composition(new TexCompositor);

    Composition* iconic = new Composition(new ArrayCompositor(100));


  • 相关阅读:
    MySql中游标的定义与使用方式
    C#操作Redis SortedSet 有序集合
    C#操作Redis Set 无序集合
    C#操作Redis Hash数据表
    C#操作Redis List 列表
    C#操作Redis String字符串(1)
    Code First 到现有数据库 Code First From DB
    C#中Typeof 是什么?和GetType 有什么关系?
    从政策到产品,一次聊懂互联网+护理
    全国及各省市级互联网医疗 相关行业政策汇总
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983114.html
Copyright © 2011-2022 走看看