4. 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
5. Applicability
The client cannot know anything about the
implementation. Hence if the implementation is
changed, the client code will not be recompiled
6. 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
7. Example
Window class realizes its functionalities through
the functions of WindowImp class
8. Example - Window.h
class 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();
};
9. Explanation – Window class
It 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
11. 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
12. 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;
}
14. Window class
It creates the specific implementation class
through the factory class WindowSystemFactory
15. WindowSystemFactory Class
class WindowImp;
class WindowSystemFactory
{
public:
static WindowSystemFactory* Instance();
WindowImp* MakeWindowImp(const int type_of_implementation );
private:
WindowSystemFactory();
static WindowSystemFactory* instance;
};
16. WindowSystemFactory class
WindowSystemFactory* 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;
}
17. 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);
}
18. 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
19. 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
20. 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
21. 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
22. 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