您的位置:首页 > 其它

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

2005-07-21 11:40 483 查看
设计模式之桥接(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.协作:

Abstraction将Client的请求转发给它的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;

}

/*

*/

//---------------------------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: