设计模式之桥接(Bridge)---对象结构性模式

设计模式之桥接(Bridge---对象结构性模式(设计模式笔记)

1.意图

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

 

 

2.别名   Handle/Body

 

 

3.动机

       当一个抽象可能有多个实现时,通常用继承来协调它们.但不够灵活.可以用Bridge模式.

 

 

4.适用性

       1)你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。

       2)类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

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

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

 

 

5.结构

              

 

 

6.参与者

* Abstraction

---定义抽象类的接口.

---维护一个指向Implementor类型的指针.

*RefinedAbstraction

---扩充由Abstrastion定义的接口.

*Implementor

---定义实现类的接口,该接口不一定要与Abstraction接口完全一致;一般是: Implementor接口仅提供基本操作,Abstraction则定义了基于这些基本操作的较高层次的操作.( 重点理解)

* ConcreteImplementor接口并定义它的具体实现.

 

 

7.协作:

       AbstractionClient的请求转发给它的Implementor对象.( 重点理解)

 

 

8.代码示例:

//------------------------------------------------------

 

 

 

 

/*    1)与模式对应关系

          Abstraction----Window

       RefineAbstraction---IconWindow&&ApplicationWindow

       Implementor----ImpWindow

       ConcreteImplementor---XWindowImp,PMWindowImp

2)结构图

   

 

 

      

*/

class Body {

  public:

   void Ref();

   void Unref();

   int RefCount();

 private:

};

 

 

class Handle {

  public:

    Handle& operator=(const Handle& other);

  private:

    Body* _body;

};

/*

*/

Handle& Handle::operator= (const Handle& other)  {

    other._body->Ref();

    _body->Unref();

 

 

    if (_body->RefCount() == 0) {

        delete _body;

    }

    _body = other._body;

 

 

    return *this;

}

/*

*/

#include "Geom.H"

#include "math.h"

class Window;

 

 

class View {

  public:

    DrawOn(Window*);

};

 

 

class WindowImp;

struct Display;

typedef unsigned int Drawable;

typedef struct XXX { int y; }  *GC;

extern XDrawRectangle(

    Display*,

    Drawable,

    GC,

    int,

    int,

    unsigned int,

    unsigned int

);

 

 

struct PPOINTL {

    Coord x;

    Coord y;

};

const int GPI_ERROR = 1;

 

 

typedef int HPS;

int GpiBeginPath(HPS, unsigned long);

int GpiSetCurrentPosition(HPS, PPOINTL*);

int GpiPolyLine(HPS, unsigned long, PPOINTL*);

int GpiEndPath(HPS);

void  ReportError();

void GpiStrokePath(HPS, unsigned long, unsigned long);

class WindowSystemFactory {

  public:

    static WindowSystemFactory* Instance();

    WindowImp* MakeWindowImp();

};

 

 

/*

*/

class Window {

public:

    Window(View* contents);

 

 

    // requests handled by window

    virtual void DrawContents();

/*

*/

    virtual void Open();

    virtual void Close();

    virtual void Iconify();

    virtual void Deiconify();

/*

*/

    // requests forwarded to implementation

    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(const char*, const Point&);

/*

*/

protected:

    WindowImp* GetWindowImp();

    View* GetView();

/*

*/

private:

    WindowImp* _imp;

    View* _contents; // the window's contents

};

/*

*/

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(const char*, Coord, Coord) = 0;

    virtual void DeviceBitmap(const char*, Coord, Coord) = 0;

    // lots more functions for drawing on windows...

protected:

    WindowImp();

};

/*

*/

class ApplicationWindow : public Window {

public:

    // ...

    virtual void DrawContents();

};

 

 

void ApplicationWindow::DrawContents () {

    GetView()->DrawOn(this);

}

/*

*/

class IconWindow : public Window {

public:

    // ...

    virtual void DrawContents();

private:

    const char* _bitmapName;

};

/*

*/

void IconWindow::DrawContents() {

    WindowImp* imp = GetWindowImp();

    if (imp != 0) {

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

    }

}

/*

*/

void Window::DrawRect (const Point& p1, const Point& p2) {

    WindowImp* imp = GetWindowImp();

    imp->DeviceRect(p1.X(), p1.Y(), p2.X(), p2.Y());

}

/*

*/

class XWindowImp : public WindowImp {

public:

    XWindowImp();

 

 

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

    // remainder of public interface...

private:

    // lots of X window system-specific state, including:

    Display* _dpy;

    Drawable _winid;  // window id

    GC _gc;           // window graphic context

};

/*

*/

class PMWindowImp : public WindowImp {

public:

    PMWindowImp();

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

 

 

    // remainder of public interface...

private:

    // lots of PM window system-specific state, including:

    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* Window::GetWindowImp () {

    if (_imp == 0) {

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

    }

    return _imp;

}

/*

*/

 

 

//---------------------------------------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值