bridge pattern

22
Design Pattern Training Bridge Pattern by Somenath Mukhopadhyay [email protected]

Upload: somenath-mukhopadhyay

Post on 25-May-2015

362 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Bridge Pattern

Design Pattern Training

Bridge Patternby

Somenath Mukhopadhyay

[email protected]

Page 2: Bridge Pattern

Purpose

To decouple abstraction from implementation so that the two can be extended/reused independently

Page 3: Bridge Pattern

Class Diagram

Page 4: Bridge Pattern

Applicability

Helps us in avoiding a permanent binding between an abstraction and implementation

It might be useful if we want to select/switch the implementation at runtime

Abstraction and implementation can be extended independently. Different abstraction can be attached to different implementation

Page 5: Bridge Pattern

Applicability

The client cannot know anything about the implementation. Hence if the implementation is changed, the client code will not be recompiled

Page 6: Bridge Pattern

Example

We have two classes – Window and WindowImp

Window class has got two subclasses – IconWindow and TransientWindow

WindowImp class has got two subclasses – XwindowImp and PMWindowImp

Page 7: Bridge Pattern

Example

Window class realizes its functionalities through the functions of WindowImp class

Page 8: Bridge Pattern

Example - Window.hclass Window{public:

Window();

WindowImp* GetWindowImp(const int type_of_implementation );

void DrawRect(const Coord& aTopLeft, const Coord& aBottomRight);

void DrawLine(const Coord& aBegin, const Coord& aEnd);

private:WindowImp* imp;

};

class IconWindow : public Window{public:

IconWindow();void DrawBorder(const Coord& aTopLeft, const Coord& aBottomRight);

};

class TransientWindow : public Window{public:

TransientWindow();};

Page 9: Bridge Pattern

Explanation – Window classIt has got the basic functionalities like DrawRect and DrawLine

It has got GetWindowImp to bind a specific Window to another specific implementation

The IconWindow class has its own function DrawBorder which is implemented through the Window class functions

TransientWindow class just uses Window class functions

Page 10: Bridge Pattern

WindowImp classclass WindowImp{public:

WindowImp();virtual void DeviceLine(const Coord& aBeginningPoint, const Coord& aEndPoint) = 0;virtual void DeviceRect(const Coord& aTopLeft, const Coord& aBottomRight) = 0;

};

class XWindowImp : public WindowImp{public:

XWindowImp();virtual void DeviceLine(const Coord& aBeginningPoint, const Coord& aEndPoint);virtual void DeviceRect(const Coord& aTopLeft, const Coord& aBottomRight);

};

class PMWindowImp : public WindowImp{public:

PMWindowImp();virtual void DeviceLine(const Coord& aBeginningPoint, const Coord& aEndPoint);virtual void DeviceRect(const Coord& aTopLeft, const Coord& aBottomRight);

};

Page 11: Bridge Pattern

Explanation – WindowImp class

Its an abstract class having two pure virtual functions

Two subclasses have been derived from it – XWindowImp and PMWindowImp

These two subclasses override the base class functions according to the specific needs

Page 12: Bridge Pattern

WindowImp class

WindowImp::WindowImp() {}

XWindowImp::XWindowImp(){}

PMWindowImp::PMWindowImp() {}

void XWindowImp::DeviceLine(const Coord& aBeginningPoint, const Coord& aEndPoint){

cout<<"Draw the XWindow version of Line draw"<<endl;}

void XWindowImp::DeviceRect(const Coord &aTopLeft, const Coord &aBottomRight){

cout<<"Draw the XWindow version of Rectangle draw"<<endl;}

void PMWindowImp::DeviceLine(const Coord &aBeginningPoint, const Coord &aEndPoint){

cout<<"Draw the PMWindow version of Line draw"<<endl;}

void PMWindowImp::DeviceRect(const Coord &aTopLeft, const Coord &aBottomRight){

cout<<"Draw the PMWindow version of Rectangle draw"<<endl;

}

Page 13: Bridge Pattern

Window classWindow::Window(){

imp = 0;}

WindowImp* Window::GetWindowImp(const int type_of_implementation){

imp = WindowSystemFactory::Instance()-> MakeWindowImp(type_of_implementation);return imp;

}

void Window::DrawLine(const Coord& aBegin, const Coord& aEnd){

imp->DeviceLine(aBegin, aEnd);}

void Window::DrawRect(const Coord &aTopLeft, const Coord &aBottomRight){

imp->DeviceRect(aTopLeft,aBottomRight);}

IconWindow::IconWindow() {}

void IconWindow::DrawBorder(const Coord& aTopLeft, const Coord& aBottomRight){

DrawRect(aTopLeft, aBottomRight);}

TransientWindow::TransientWindow() {}

Page 14: Bridge Pattern

Window class

It creates the specific implementation class through the factory class WindowSystemFactory

Page 15: Bridge Pattern

WindowSystemFactory Class

class WindowImp;

class WindowSystemFactory{public:

static WindowSystemFactory* Instance();WindowImp* MakeWindowImp(const int type_of_implementation );

private:WindowSystemFactory();static WindowSystemFactory* instance;

};

Page 16: Bridge Pattern

WindowSystemFactory classWindowSystemFactory* WindowSystemFactory::instance = 0;

WindowSystemFactory::WindowSystemFactory() {}

WindowSystemFactory* WindowSystemFactory::Instance(){

if (NULL = = instance){

instance = new WindowSystemFactory;}

return instance;}

WindowImp* WindowSystemFactory::MakeWindowImp(const int type_of_implementation){

if (type_of_implementation == XwindowImplementation)

return new XwindowImp;

if (type_of_implementation == PMWindowImplementation)

return new PMWindowImp;

return 0;}

Page 17: Bridge Pattern

Client of Abstraction

IconWindow* XIconWindow = new IconWindow;

XIconWindow->GetWindowImp(XWindowImplementation);

const Coord pt0(1,2);const Coord pt1(7,8);

XIconWindow->DrawBorder(pt0,pt1);

TransientWindow* PMTransientWindow = new TransientWindow;

PMTransientWindow->GetWindowImp(PMWindowImplementation);

PMTransientWindow->DrawRect(pt0,pt1);

IconWindow* PMIconWindow = new IconWindow;

PMIconWindow->GetWindowImp(PMWindowImplementation);

PMIconWindow->DrawLine(pt0,pt1);}

Page 18: Bridge Pattern

Explanation

There are two Window objects – XIconWindow and PMTransientWindow

As the name suggests XiconWindow will create an IconWindow object and it will attach itself to an XWindowImp implementation

On the other hand PMTransientWindow will create a TransientWindow object and attach itself to an PMWindowImp implementation

Page 19: Bridge Pattern

Explanation

The attachment of an Window object to a specific Implementation is done through GetWindowImp function

This function takes the help of the WindowSystemFactory class to create specific implementation

Page 20: Bridge Pattern

Explanation

Similarly we can have one IconWindow object and attach it to a PMWindowImp implementation or a TransientWindow object and attach it to a XwindowImp implementation

Page 21: Bridge Pattern

contd...

If there is only one implementation, there is no need to create an abstract Implementor class.

This is only one-to-one relationship between the abstraction and its implementation

However, it helps us in avoiding the recompilation of the client code when the implementation class is changed

Page 22: Bridge Pattern

contd...

In the example, we have attached an abstraction to its implementation by taking the help of the WindowSystemFactory class

This can also be achieved in the constructor of the Window class. For example the window class can instantiate the specific implementation depending on the parameter passed to its constructor