zoukankan      html  css  js  c++  java
  • 设计模式 笔记 适配器模式 Adapter


    //---------------------------15/04/13----------------------------


    //Adapter 适配器模式 ----类对象结构型模式


    /*

        1:意图:

            将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容

            而不能一起工作的那些类可以一起工作。

        2:别名: Wrapper

        3:动机

        4:适用性:

            1>你想使用一个已经存在的类,而它的接口不符合你的需求。

            2>你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口

              可能不一定兼容的类)协同工作。

            3>(仅对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化

              以匹配它们的接口。对象适配器可以适配它的父类接口。

        5:结构:

            1>类适配器:

                Client-------->Target:          Adaptee:

                               Request()        SpecificRequest()

                                  |                     |

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

                                            |

                                         Adapter:

                                         Request()

                                         { SpecificRequest() }

            2>对象适配器:

                Client-------->Target:

                               Request()

                                  |             ----->Adaptee:

                                  |     adaptee |     SpecificRequest()

                               Adapter-----------

                               Request()

                              { adaptee->SpecificRequest() }

        6:参与者:

            1>Target:定义了Client使用的与特定领域相关的接口。

            2>Client:与符合Target接口的对象协同。

            3>Adaptee:定义了一个已经存在的接口,这个接口需要适配。

            4>Adapter:对Adaptee的接口与Target接口进行适配。

        7:协作:

            ClientAdapter实例上调用一些操作。接着适配器调用Adaptee的操作实现这个请求。

        8:效果:

            1>类适配器:

                1)用一个具体的Adapter类对AdapteeTarget进行匹配。结果是当我们想要匹配一个类

                  以及所有它的子类时,类Adapter将不能胜任工作。

                2)使得Adapter可以重定义Adaptee的部分行为,因为AdapterAdaptee的一个子类。

                3)仅仅引入了一个对象,并不需要额外的指针以间接得到Adaptee

            2>对象适配器:

                1)允许一个Adapter与多个Adaptee--Adaptee本身以及它的所有子类(如果有子类的话)

                  同时工作。Adapter也可以一次给所有的Adaptee添加功能。

                2)使得重定义Adaptee的行为比较困难,这就需要生成Adaptee的子类并且使得Adapter引用

                  这个子类而不是引用Adaptee本身。

            3>需要考虑的其他因素:

                1)Adapter的匹配程度。对Adaptee的接口与Target的接口进行匹配的工作量各个Adapter

                  可能不一样。工作范围可能是,从简单的接口转换(例如改变操作名)到支持完全不同的操作

                  集合。Adapter的工作量取决于Target接口与Adaptee接口的相似程度。

                2)可插入的Adapter。当其他的类使用一个类时,如果所需的假定条件越少,这个类就更具可

                  复用性。如果将接口匹配构建为一个类,就不需要假定对其他的类可见的是一个相同的接口。

                  也就是说,接口匹配使得我们可以将自己的类加入到一些现有的系统中去,而这些系统对

                  这个类的接口可能会有所不同。

                3)使用双向适配器提供透明操作。使用适配器的一个潜在问题是,它们不对所有的客户都透明。

                  被适配的对象不再兼容Adaptee的接口,因此并不是所有Adaptee对象可以被使用的地方它

                  都可以被使用。双向适配器提供了这样的透明性。在两个不同的客户需要用不同的方式查看

                  同一个对象时,双向适配器尤其有用。

        9:实现:

            注意的问题:

            1>使用c++实现适配器。在使用c++实现适配器类时,Adapter类应该采用public方式继承Target

              并且用private方式继承Adaptee类。因为Adaptee的接口只是拿来用的,不需要传承下去。

            2>可插入的Adapter 有许多方法可以实现。一共有三种。

                1)首先(三种实现都要做的)

                    Adaptee找到一个窄接口,即可用于适配的最小操作集。因为包含较少操作的窄接口相对

                    包含较多操作的宽接口比较容易进行匹配。

                2)实现途径:

                    a):使用抽象操作。窄接口定义相应的抽象操作,由子类来实现这些抽象操作。

                    b):使用代理对象。在客户类中存放一个代理,并调用代理的抽象方法,Adapter可以实现

                        抽象方法来达到适配的目的。

                    c):参数化的适配器。

        10:代码示例:                                                                    */


    //类适配器:

    //Target

    class Shape

    {

    public:

        Shape();

        virtual void BoundingBox(Point& bottomLeft, Point& topRight)const;

        virtual Manipulator* CreateManipulator() const;

    };


    //Adaptee

    class TextView

    {

    public:

        TextView();

        void GetOrigin(Coord& x, Coord& y) const;

        void GetExtent(Coord& width, Coord& height) const;

        virtual bool IsEmpty() const;

    };


    //Adapter只需要实现Target的接口,但是要使用Adaptee的接口

    class TextShape: public Shape, private TextView

    {

    public:

        TextShape();

        

        virtual void BoundingBox(Point& bottomLeft, Point& topRight) const;

        virtual bool IsEmpty() const;

        virtual Manipulator* CreateManipulator() const;

        

    };


    //Coord接口类型为Point类型

    void TextShape::BoundingBox(Point& bottomLeft, Point& topRight) const

    {

        Coord bottom, left, width, height;

        GetOrigin(bottom, left);

        GetExtent(width, height);

        

        bottomLeft = Point(bottom, left);

        topRight = Point(bottom + height, left + width);

        

    }



    bool TextShape::IsEmpty() const

    {

        return TextView::IsEmpty();

    }


    //需要自己实现,Adaptee并没有这功能。

    Manipulator* TextShape::CreateManipulator() const

    {

        return new TextManipulater(this);

    }


    //对象适配器,操作几乎完全一样,只需要把相应的从adaptee继承来的操作改成使用

    //_text来做的操作

    class TextShape : public Shape

    {

    public:

        TextShape(TextView*);

        

        virtual void BoundingBox(Point& bottomLeft, Point& topRight) const;

        virtual bool IsEmpty() const;

        virtual Manipulator* CreateManipulator() const;

    private:

        TextView* _text;

    };


    TextShape::TextShape(TextView* t)

    {

        _text = t;

    }

    void TextShape::BoundingBox(Point& bottomLeft, Point& topRight) const

    {

        Coord bottom, left, width, height;

        _text->GetOrigin(bottom, left);

        _text->GetExtent(width, height);

        

        bottomLeft = Point(bottom, left);

        topRight = Point(bottom + height, left + width);


    }


    Manipulator* TextShape::CreateManipulator() const

    {

        return new TextManipulater(this);

    }


    //虽然对象适配器实现起来稍微复杂了一点,但是更加灵活,可以活用adaptee的子类。



  • 相关阅读:
    Ubuntu下官方QQ崩溃的解决
    [转]PHP函数的实现原理及性能分析
    [收藏的资料]301重定向的实现方法
    手动配置Ubuntu 指定DNS服务器地址
    C# FTP操作类
    vs2010 快捷键大全
    分享一个不错的VS插件——CodeMap
    C# 快速的批量修改重命名.net程序的命名空间(一)转 tianyaxiang
    jquery 的 ajax 程序 简单的
    winform窗体间传值
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983137.html
Copyright © 2011-2022 走看看