• 设计模式 笔记 装饰模式 Decorator




    //---------------------------15/04/17----------------------------



    //Decorator 装饰模式----对象结构型模式

    /*

        1:意图:

            动态地给一个对象添加额外的职业,就增加功能来说,Decorator模式相比生成子类更为灵活。

        2:别名:

            包装器(Wrapper)

        3:动机:

        4:适用性:

            1>在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

            2>处理那些可以撤销的职责。

            3>当不能采用生成子类的方法进行扩充时:

                1)可能有大量独立的扩展,为支持每一种组合将产生大量的子类。

                2)类定义被隐藏,或类定义不能用于生成子类。

        5:结构:

                    Component:<------------------

                    Operation                   |

                        |                       |

                        |                       |

                ------------------              |

                |                |              |

        ConcreteComponent:      Decorator:      |

        Operation()             component--------

                                Operation()

                                { component->Operation() }

                                    |

                                    |

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

                            |                  |

                    ConcreteDecoratorA: ConcreteDecoratorB:

                    Operation()         Operatione()

                    addedState()        {   Decorator::Operation();

                                            AddedBehavior();        }

                                        AddedBehavior()

        6:参与者:

            1>Component

                定义一个对象接口,可以给这些对象动态地添加职责。

            2>ConcreteComponent

                定义一个对象,可以给这个对象添加职责。

            3>Decorator

                维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。

            4>ConcreteDecorator

                向组件添加职责。

        7:协作:

            Decorator将请求转发给它的Component对象,并有可能在转发请求前后执行一些附加的动作。

        8:效果:

            1>优点:

                1)比静态继承更灵活。

                    Decorator模式提供了更加灵活的向对象添加职责的方式,在运行时刻添加和删除职责。

                    相比于使用继承,Decorator模式可以很容易地重复添加一个特性,而重复继承很容易出错。

                2)避免在层次结构高层的类有太多特征。

                    Decorator模式提供了一种即用即付的方法来添加职责。可以对一个简单的类扩展出复杂的

                    功能。

            2>缺点:

                1)Decorator和它的Component不一样。

                    被装饰了的组件和没装饰时是有差别的,因此,使用装饰时不应该依赖对象标识。

                    装饰后,在别的对象看来,就是Decorator类了,而不是ConcreteCompnent类了

                2)有许多小对象。

                    采用Decorator模式进行系统设计往往会产生许多看上去类似的小对象,这些对象仅仅在他们相互

                    连接的方式上有所不同,而不是它们的类或是他们的属性值有所不同。所以这些系统很难学习和排错。

        9:实现:

            1>接口的一致性:

                装饰对象的接口必须与它所装饰的Component的接口是一致的,因此所有的ConcreteDecorator类必须

                有一个公共的父类。

            2>省略抽象的Decorator类:

                当你仅需要添加一个职责时,没有必要定义抽象的Decorator类。

            3>保持Component类的简单性:

                为了接口的一致性,组件和装饰都必须继承自Component类,所以保持这个类的简单性很重要。

                也就是把这个类设计目的集中于接口设计,而不是存储数据。

            4>改变对象外壳与改变对象内核:

                可以把Decorator类当作是一个对象的外壳,添加Decorator类可以改变一个对象的行为,但是当

                Component类很庞大时,添加一个Decorator类代价就显得很大。所以可以选择使用另外一种模式:

                Strategy模式,组件可以将一些行为转发给一个独立的策略对象,通过改变策略对象,就可以达到

                改变或扩充组件的功能。

        10:代码示例:                                                                            */


    //Component类,提供了接口

    class VisualComponent

    {

    public:

        VisualComponent();

       virtual void Draw();

       virtual void Resize();

        ...

    };



    //abstract Decorator

    class Decorator :public VisualComponent

    {

    public:

        Decorator(VisualComponent*);

        

       virtual void Draw();

       virtual void Resize();

        ...

    private:

        VisualComponent* _component;

    };


    void Decorator::Draw()

    {

        _component->Draw();

    }


    void Decorator::Resize()

    {

        _component->Resize();

    }


    //ConcreteDecorator 在自己的Draw()中添加了要添加的职责--绘制边框

    class BorderDecorator :public Decorator

    {

    public:

        BorderDecorator(VisualComponent*,int borderWidth);

        

       virtual void Draw();

    private:

       void DrawBorder(int);

        

    private:

       int _width;

    };


    void BorderDecorator::Draw()

    {

        Decorator::Draw();

        DrawBorder(_width);

    }


    //这里的SetContents以一个Component指针为参数,来进行一些操作,

    //通过装饰就可以传入一个装饰过的类

    void Window::SetContents(VisualComponent* contents)

    {

        ...

    }


    Window* window =new Window;

    //未经装饰的类,TextView是继承自Component类的ConcreteComponent

    TextView* textView =new TextView;


    //它可以被这样传入

    window->SetContents(textView);


    //也可以通过装饰来传入,这样装饰就增加了起码两个Component大小的内存了,所以

    //如果Compnent如果很庞大的话,使用代价会很高。

    window->SetContents(new BorderDecorator(new ScrollDecorator(textView),1));


    //再考虑一个问题,如果深度很深的话,实现起来效率也会下降。

    //何谓深度,就是装饰了很多很多次,这里的调用其实就是通过指针不断访问下一个对象调用Draw(),就和链表一样,

    //如果深度很深,那么就像遍历链表一样。

    //这时可以考虑实现中最后一点说的,使用strategy模式。



  • 相关阅读:
    【UML建模】UML类图几种关系的总结
    【架构框架】IoC框架
    【AutoMapper基础】值解析器--Custom value resolvers
    【AutoMapper基础】简单示例--Flattening
    【AutoMapper简介】
    【UML建模】UML类图符号简介
    【.Net基础02】XML序列化问题
    【.net 基础01】ReferenceEquals,Equals,==的区别
    【Visual Studio】利用预编译命令发布不同的版本
    【Windows Phone 8】五角星评价控件
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983132.html
Copyright © 2020-2023  润新知