七、Bridge(桥接)
情景举例:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
代码示例:
/* 抽象部分的接口
*/
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 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;
};
/* 最关键的部分:抽象部分与实现部分的桥接处。
这部分可以有各种变形,例子中使用了抽象工厂和单件。
也可以使用参数来指定实现部分。
*/
WindowImp* Window::GetWindowImp () {
if (_imp == 0) {
_imp = WindowSystemFactory::Instance()->MakeWindowImp();
}
return _imp;
}
/*
*/
个人理解:
桥接模式与对象适配器的结构非常相似,但他们主要的区别在于:对象适配器是使得2个无关的类能够协同工作,一般在系统的后期使用;而桥接则是在系统开始时就使用,目的是使得接口与实现部分独立并可以分别变化。