zoukankan      html  css  js  c++  java
  • 设计模式 笔记 桥接模式 Bridge




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


    //Bridge 桥接模式----对象结构型模式


    /*

        1:意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

        2:别名:Handle

        3:动机

        4:适用性:

            1>你不希望在抽象和它的实现部分之间有一个固定的绑定关系。比如在程序运行时刻实现部分

              应该可以被选择或切换。

            2>类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时,Bridge模式使你

              可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

            3>对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。

            4>你想对客户完全隐藏抽象的实现部分。在c++中,类的表示在类接口中时可见的。

            5>由许多类要生成,这时要把对象分解成两个部分。

            6>你想在多个对象间共享实现,但同时要求客户并不知道这一点,

        5:结构:

            client

             

              ------->Abstraction:

                        imp----------------------------->Implementor:

                        Operation()                      OperationImp()

                        { imp->OperationImp();}               |

                           |                                  |

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

                   RefinedAbstraction:           |                           |

                                    ConcreteImplementorA:       ConcreteImplementorB:

                                    OperationImp()              OperationImp()



        6:参与者:

            1>Abstraction

                1)定义抽象类的接口。

                2)维护一个指向Implementor类型对象的指针。

            2>RefinedAbstraction

                扩充由Abstraction定义的接口。

            3>Implementor

                定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以

                完全不同。一般来讲,Implementor接口仅提供基础操作,而Abstractor则定义了基于这些

                操作的较高层次的操作。

            4>ConcreteImplementor

                实现了Implementor接口并定义它的具体实现。

        7:协作:

            Abstractionclient的请求转发给它的Implementor对象。

        8:效果:

            1>分离接口及其实现部分。一个实现未必不变地绑定在一个接口上。抽象类的实现可以在运行时刻进行

              配置,一个对象甚至可以在运行时刻改变它的实现。

              AbstractionImplementor分离有助于降低对实现部分编译时刻的依赖性,当改变一个实现类

              时,并不需要重新编译Abstraction类和它的客户程序。为了保证一个类库的不同版本之间的二进制

              兼容性,一定要有这个性质。

              另外接口和实现分离有助于分层,从而产生更好的结构化系统,系统的高层部分仅需知道Abstraction

              Implementor即可。

            2>提高可扩充性。你可以独立地对AbstractionImplementor层次结构进行扩充。

            3>实现细节对客户透明。你可以对客户隐藏实现细节。

        9:实现:

            1>仅有一个Implementor,在仅有一个实现的时候,没有必要创建一个抽象的Implemntor类,这是

              Bridge模式的退化情况;在AbstractionImplementor之间有一种一对一的关系。尽管如此,

              如果你希望改变一个类的实现不会影响已有的客户程序时,模式的分离机制还是必要的。

            2>创建正确的Implementor对象。当存在多个Implementor类的时候,如何确定创建哪一个

              Implementor类:

                1)传递参数来选择构造相应的ConcreteImplementor类。

                2)交给另外一个对象,通常是一个factory对象,向factory申请一个对象。

        10:代码示例:                                                                        */


    //Abstraction:定义了Window应有的接口

    class Window

    {

    public:

        Window(View* contents);

        

       virtual void DrawContents();

       virtual void Open();

       virtual void Close();

       virtual void Iconify();

       virtual void Deiconify();

        

       virtual void SetOrigin(const Point& at);

       virtual void SetExtent(const Point& extent);

       virtual void Raise();

       virtual void Lower();

       virtual void DrawLine(const Point&,const Point);

       virtual void DrawRect(const Point&,const Point);

       virtual void DrawPolygon(const Point[],int n);

       virtual void DrawText(constchar*, const Point&);

        

    protected:

        WindowImp* GetWindowIpm();

        View* GetView();

        

    private:

        Window* _imp;

        View* _contexts;

    };


    //Implementor:定义了Implementor应有的接口

    class WindowImp

    {

    public:

       virtual void ImpTop() =0;

       virtual void ImpBottom() =0;

       virtual void ImpSetExtent(const Point&) =0;

       virtual void ImpSetOrigin(const Point&) =0;

        

       virtual void DeviceRect(Coord, Coord, Coord, Coord) =0;

       virtual void DeviceText(constchar*, Coord, Coord) = 0;

       virtual void DeviceBitmap(constchar*, Coord, Coord) = 0;

        ...

        

    protected:

        WindowImp();

    };



    //RefinedAbstraction

    class ApplicateionWindow :public Window

    {

    public:

       virtual void DrawContents();

        ...

    };


    void ApplicateionWindow::DrawContents()

    {

        GetView()->DrawOn(this);

    }



    //RefinedAbstraction 使用Implementor的接口来画图

    class IconWindow:public Window

    {

    public:

       virtual void DrawContents();

        ...

    private:

       const char* _bitmapName;

    };


    void IconWindow::DrawContents()

    {

        WindowImp* imp = GetWindowIpm();

       if(imp != 0)

        {

            imp->DeviceBitmap(_bitmapName,0.0, 0.0);

        }

    }


    //ConcreteImplementor  实现了底层操作。

    class XwindowImp :public WindowImp

    {

    public:

        XwindowImp();

       virtual void DeviceRect(Coord, Coord, Coord, Coord);

        ...

    private:

        Display* _dpy;

        Drawable _winid;

        Gc _gc;

    };


    //ConcreteImplementor

    class PMWindowImp :public WindowImp

    {

    public:

        PMWindowImp();

       virtual void DeviceRect(Coord, Coord, Coord, Coord);

        ...

    private:

        HPS _hps;

    };


    void XwindowImp::DeviceRect(Coord x0, Coord y0, Coord x1, Coord y1)

    {

       int x = round(min(x0, x1));

       int y = round(min(y0, y1));

       int w = round(abs(x0 - x1));

       int h = round(abs(y0 - y1));

        XDrawRectangle(_dpy, _winid, _gc, x, y, w, h);

    }


    void PMWindowImp::DeviceRect(Coord x0, Coord y0, Coord x1, Coord y1)

    {

        Coord left = min(x0, x1);

        Coord right = max(x0, x1);

        Coord bottom = min(y0, y1);

        Coord top = max(y0, y1);

        

        PPOINTL point[4];

        

        point[0].x = left;

        point[0].y = top;

        

        point[1].x = right;

        point[1].y = top;

        

        point[2].x = right;

        point[2].y = bottom;

        

        point[3].x = left;

        point[3].y = bottom;

        

       if(

           (GpiBeginPath(_hps,1L) == false) ||

           (GpiSetCurrentPosition(_hps, &point[3]) ==false) ||

           (GpiPolyLine(_hps,4L, point) == GPI_ERROR) ||

           (GPIEndPath(_hps) ==false)

          )

        {

            //report error;

        }

       else

        {

            GpiStrokePath(_hps,1L, 0L);

        }


    }



    //使用单例模式的工厂得到WindowImp的实例。

    WindowImp* Window::GetWindowIpm()

    {

       if(_imp == 0)

        {

            _imp = WindowSystemFactory::Instance()->MakeWindowImp();

        }

       return _imp;

    }








  • 相关阅读:
    c++ 11 thread 初试
    java UDP聊天与文件传输
    iOS 基础类解析
    Hadoop HA高可用集群搭建(2.7.2)
    object-c 不定參数的遍历和原理
    9.4 返回更新后的行
    java面向接口编程
    Node.js开发入门—套接字(socket)编程
    shell脚本输出带颜色字体
    shell--read命令
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983136.html
Copyright © 2011-2022 走看看