9
Structural Pattern: Bridge When 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. Chapter 4 – Page 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.

Structural Pattern: Bridge

  • Upload
    bridie

  • View
    57

  • Download
    0

Embed Size (px)

DESCRIPTION

Structural Pattern: Bridge. Chapter 4 – Page 67. When 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. - PowerPoint PPT Presentation

Citation preview

Page 1: Structural Pattern: Bridge

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.

Chapter 4 – Page 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.

Page 2: Structural Pattern: Bridge

The Bridge Pattern Chapter 4 – Page 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.

Page 3: Structural Pattern: Bridge

Example: Without Bridge PatternThree types of shapes, with each type split into two platform-dependent subtypes.

Chapter 4 – Page 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()

Page 4: Structural Pattern: Bridge

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.

Chapter 4 – Page 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()

Page 5: Structural Pattern: Bridge

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

Chapter 4 – Page 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()

MilitaryTimeImplementortimezone : String

tell()

Client

TimeImplementorhour : intminute : int

tell()

Timeimplementor : TimeImplementor

tell()

Page 6: Structural Pattern: Bridge

C++ Code for Time Zone BridgeChapter 4 – Page 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; };

Page 7: Structural Pattern: Bridge

Chapter 4 – Page 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; };

Page 8: Structural Pattern: Bridge

Chapter 4 – Page 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();}

Page 9: Structural Pattern: Bridge

Bridge Pattern AdvantagesChapter 4 – Page 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.