Post on 05-Jan-2016
Structural Pattern: BridgeWhen the abstract interface and the concrete implementation have been set up as parallel class hierarchies, it becomes difficult to independently extend either the interface or the implementation.
Chap
ter 4
– Pa
ge 1
The Bridge Pattern addresses this problem by decoupling the two class hierarchies, making them orthogonal rather than parallel.
In this way, the abstract interfaces can be platform-independent even when the concrete implementations are platform-dependent.
The Bridge PatternC
hap
ter 4
– Pa
ge 2
The Abstraction defines the client’s interface, maintaining a reference to an Implementor object, while the Refined Abstraction extends the Abstraction interface.
Client
ConcreteImplementorA
OperationImplementation()
RefinedAbstraction
Implementor::OperationImplementation()
Abstraction
Operation()
Implementor
OperationImplementation()
ConcreteImplementationB
OperationImplementation()
The Implementor defines the interface for the implementation, providing primitive operations (while the Abstraction provides the higher-level operations based on these primitives).The ConcreteImplementors implement the Implementor class, providing the platform-specific implementation details.
Example: Without Bridge PatternThree types of shapes, with each type split into two platform-dependent subtypes.
Chap
ter 4
– Pa
ge 3
Any change to one shape type (e.g., Circle) could extend its effects to the two platform-dependent subtypes (e.g., PlatformACircle, PlatformBCircle).Any change to a platform (e.g., PlatformA) could extend its effects to all three platform-dependent shape subtypes (e.g., PlatformACircle, PlatformARectangle, PlatformATriangle).
PlatformARectangle
drawHorizontalLine()drawVerticalLine()
Rectangle
draw()drawHorizontalLine()drawVerticalLine()
Shape
draw()
Client
PlatformBRectangle
drawHorizontalLine()drawVerticalLine()
Circle
draw()drawCircle()
Triangle
draw()drawLine()
PlatformACircle
drawCircle()
PlatformBCircle
drawCircle()
PlatformATriangle
drawLine()
PlatformBTriangle
drawLine()
DrawingProgramA
draw_a_line()draw_a_circle()
DrawingProgramB
drawline()drawcircle()
Example: With Bridge PatternBy decoupling the Shape abstraction from the Drawing implementor, the explosion of platform-dependent shape subclasses is avoided and the amount of redundant code is minimized.
Chap
ter 4
– Pa
ge 4
With this model, individual shape alterations and additional extensions to the Shape class will only affect the abstraction portion of the model, while platform modifications will only affect the implementor portion of the model.
Client
Rectangle
draw()
Circle
draw()
Triangle
draw()
DrawingProgramA
draw_a_line()draw_a_circle()
DrawingProgramB
drawline()drawcircle()
PlatformADrawing
drawCircle()drawLine()drawHorizontalLine()drawVerticalLine()
PlatformBDrawing
drawCircle()drawLine()drawHorizontalLine()drawVerticalLine()
Shape
draw()drawCircle()drawLine()drawHorizontalLine()drawVerticalLine()
Drawing
drawCircle()drawLine()drawHorizontalLine()drawVerticalLine()
Bridge Example: Time Zones
The interface base class (Time) has a pointer to the TimeImplementor base class, and each class in the interface hierarchy (i.e., the Time class and its subclasses) is responsible for populating the base class pointer with the correct concrete implementor class
Chap
ter 4
– Pa
ge 5
At that point, all requests from the client are simply delegated by the interface class to the encapsulated implementor class.
CivilianTime MilitaryTimeCivilianTimeImplementor
whichM : String
tell()
MilitaryTimeImplementor
timezone : String
tell()
Client
TimeImplementor
hour : intminute : int
tell()
Time
implementor : TimeImplementor
tell()
C++ Code for Time Zone Bridge
Chap
ter 4
– Pa
ge 6
#include <iostream> #include <iomanip>#include <string>using namespace std;
class TimeImplementor { public: TimeImplementor(int hr, int min) { hour = hr; minute = min; } virtual void tell() { cout << "time is " << setw(2) << hour << minute << endl; } protected: int hour, minute;};
class CivilianTimeImplementor: public TimeImplementor{ public: CivilianTimeImplementor(int hr, int min, int pm): TimeImplementor(hr, min) { if (pm) whichM = " PM"; else whichM = " AM"; } void tell() { cout << "time is " << hour << ":" << minute << whichM << endl; } protected: string whichM; };
Chap
ter 4
– Pa
ge 7
class MilitaryTimeImplementor: public TimeImplementor{ public: MilitaryTimeImplementor(int hr, int min, int zone): TimeImplementor(hr, min) { switch (zone) { case 5: { timezone = " Eastern Standard Time"; break; } case 6: { timezone = " Central Standard Time"; break; } case 7: { timezone = " Mountain Standard Time"; break; } case 8: { timezone = " Pacific Standard Time"; break; } } } void tell() { cout << "time is " << setw(2) << hour << minute << timezone << endl; } protected: string timezone; };
class Time { public: Time(){} Time(int hr, int min) { implementor = new TimeImplementor(hr, min); } virtual void tell() { implementor->tell(); } protected: TimeImplementor *implementor; };
Chap
ter 4
– Pa
ge 8
class CivilianTime: public Time { public: CivilianTime(int hr, int min, int pm) { implementor = new CivilianTimeImplementor(hr, min, pm); }};
class MilitaryTime: public Time { public: MilitaryTime(int hr, int min, int zone) { implementor = new MilitaryTimeImplementor(hr, min, zone); }};
void main() { Time* times[3]; times[0] = new Time(14, 30); times[1] = new CivilianTime(2, 30, 1); times[2] = new MilitaryTime(14, 30, 6); for (int i = 0; i < 3; i++) times[i]->tell();}
Bridge Pattern Advantages
Chap
ter 4
– Pa
ge 9
• The Bridge Pattern is particularly useful when the structure of a class (its implementor) and what the class actually does (its abstraction) tend to change frequently.
• The Bridge Pattern is most appropriate when the software model possesses two orthogonal dimensions (e.g., “what the client wants” vs. “what the platform provides”, “front-end” vs. “back-end”, “domain” vs. “infrastructure”).
• By decoupling the interface from the implementation, the Bridge Pattern facilitates the independent extensibility of each and has the desirable effect of hiding details from the client.