七、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个无关的类能够协同工作,一般在系统的后期使用;而桥接则是在系统开始时就使用,目的是使得接口与实现部分独立并可以分别变化。