Problem focus: in the previous section, we talked about the object structure mode. The main idea is the combination of objects. And has access to a typical adapter mode. This section introduces a common bridge mode. Its main idea is to separate the abstract part from the implementation part, so that the abstract part is separated from the system platform to achieve portability. Bridging mainly refers to the relationship between the abstract part and the implementation part.
Intention: Separate the abstract part from its implementation part so that they can all change independently.
Alias: Handle/Body
Motivation: When an abstraction may have multiple implementations, The general idea is to inherit multiple sub-classes with similar functions and different duties. The disadvantage of the inherited method is that the abstract part is too close to its implementation part, making it difficult to modify, expand, and reuse the abstract part and the implementation part independently. Consider the following example: a user interface toolbox that can be transplanted. Supports both X Window System and ibm pm System. Using the Inheritance Mechanism, we can define the abstract class of Window and its two sub-classes XWindow and PMWindow, which implement the Window interface on different system platforms respectively. The disadvantage of this implementation is: 1) extended Window abstraction makes it very inconvenient to apply to different types of windows or new system platforms. Assume that a sub-class IconWindow is responsible for icon processing. To support the two platforms, two new classes XIconWindow and PMIconWindow must be implemented. That is, if we need components that support various functions, we have to implement two subclasses for each component. 2) The Inheritance mechanism makes the Customer Code relevant to the platform. The result is that the customer Code also depends on the current platform, which makes it difficult for the customer to be transplanted to other platforms. Improvement goal: when creating code, the customer does not involve the specific implementation part, but only the implementation part of the window depends on the platform where the application runs. In this way, the Customer Code does not involve a specific platform when creating a window. Use the Bridge Mode to solve this problem.
- Place the Window abstraction and Its Implementation in an independent class hierarchy.
- A class hierarchy is applicable to Window Interfaces.
- Another independent class hierarchy is designed for the implementation of platform-related Windows. The root class of this class hierarchy is WindowImp. All operations on the Window subclass are implemented using the abstract operations in the WindowImp interface. This separates the abstract of the window from the implementation of the system platform. Therefore, the relationship between windows and WindowImp is called Bridge.
Applicability: the following uses the Bridge Mode:
- You do not want to have a fixed binding relationship between the abstraction and its implementation. For example, the implementation part can be selected or switched during the running of the program.
- Class abstraction and its implementation should be expanded by generating sub-classes. In this case, the bridge mode allows you to combine different abstract interfaces and implementation parts and expand them separately.
- The modification of an abstract implementation part should not affect the customer, that is, the customer does not have to re-compile.
- You want to completely hide the abstract implementation part from the customer. In C ++, the class representation is visible in the class interface.
- To share the implementation among multiple objects, the customer is not required to know this. Structure:
Vc + release/asqK2qNLly/release/PXqreiuPjL/release + release/t9ajurPpz/PA4LXEyrXP1r/release/zyfXWwb/release/ WPGxpPszhuN +/ycCps + TQ1DxsaT7Ktc/tests + tests/y + zb/tests/y/ydLUzai5/bSrtd24 + tests/tests + tests /samples/NK7tM6 + samples/samples + 4vdqjrNXiuPa21M/samples/yy/samples/Huus + howozILmyz + samples/OjutL9yOvS/dPDvMbK/cb3u/Samples /keys/O907/aus3L/LXEyrXP1rK/keys/dfToaMKV2luZG93wODOqr/keys/zwOChowo8cHJlIGNsYXNzPQ = "brush: java; "> 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 Points & at); virtual void SetExtent (const Points & 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 Points &); protected: WindowImp * GetWindowImp (); View * GetView (); private: WindowImp * _ imp; View * _ contents ;};
Window maintains a reference to WindowImp. The WindowImp abstract class defines an interface for the underlying Window system.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*, Cood, Coord) = 0; // lots more functions for drawing on windows...protected: WindowImp();};
The subclass of Window defines the different types of Windows that may be used by the application process, such as the application Window, icon, temporary dialog box Window, and the moving Panel of the Toolbox. For example, the ApplicationWindow class implements the DrawContents operation to plot the stored View Example:class ApplicationWindow : public Window{public: virtual void DrawContents();};void ApplicationWindow::DrawContents(){ GetView()->DrawOn(this);}
For example, IconWindow stores the bitmap name corresponding to the icon it displays. (Code omitted) We can also define many other types of window classes.
Window operations are defined by the WindowImp interface. For example, before calling WidowImp to draw a rectangle in a window, DrawRect must extract four coordinate values from its two Point parameters.void Window::DrawRect(const Point& p1,const Point& p2){ WindowImp* imp = GetWindowImp(); imp->DeviceRect(p1.X(), p1.Y(), p2.X(), p2.Y());}
The specific WindowImp subclass supports different window systems. The XwindowImp subclass supports the XWindow window system.class XWindowImp : public WindowImp{public: XWindowImp(); virtual void DeviceRect(Coord, Coord, Coord, Coord);private: // lots of X Window system-specific state, including: Display* _dpy; Drawable _winid; GC _gc;};
For the PM system, we define the PMWindowImp class. (Code omitted)
These sub-classes use the basic operations of the window system to implement WindowImp operations. For example, the X Window System implements DeviceRect:void XWindowImp::DeviceRect(){ int x = round(min(x0, x1)); int y = round(min(y0, y1)); int w = round(abs(x0 - x1)); int h = round(abs(x0 - x1)); XDrawRectangle(_dpy, _winid, _gc, x, y, w, h);}
PM may have different implementations for the same operation, which enables platform-based implementation.
So how can a window get the correct WindowImp subclass instance? You can get a correct instance from an abstract factory in the GetWindowImp operation of Window.WindowImp * Window: GetWindow () {if (_ imp = 0) {_ imp = WindowSystemFactory: Instance ()-> MakeWindowImp (); // WindowSystemFactory :: the Instance () function returns an abstract factory // This factory is responsible for processing all objects related to a specific window system // At the same time, this abstract factory implementation is called a single piece (single sample mode )} return _ imp ;}
Related mode: the abstract factory mode can be used to create and configure a specific bridge mode. The adapter mode is used to help irrelevant classes work collaboratively. The bridge mode allows the abstract interfaces and implementations to be changed independently.
Reference: Design Pattern: Basis for reusable Object-Oriented Software