////////////////////////////////////////////////////////////////////////////////
// Adapter pattern
// - Convert the interface of a class into another interface clients expect.
// Adapters lets classes work together that couldn't otherwise because of
// incompatible interfaces.
// - Interface adaptation lets us incorporate our class into existing systems
// that might expect different interfaces to the class.
//
// Author : ZAsia
// Data : 15/05/07
// Warning : In practice, declaration and implementation should be
// separated(in .h and .cpp).
////////////////////////////////////////////////////////////////////////////////
#include
using namespace std;
#undef CLASS_ADAPTER
// Target
// - defines the domain-specific interface that Client uses.
class Target
{
public:
virtual void Request() { cout << "Target::Request" << endl; }
};
// Adaptee
// - defines an existing interface that needs adapting.
class Adaptee
{
public:
void SpecificRequest() { cout << "Adaptee::SpecificRequest" << endl; }
};
// Adapter
// - adapts the interface of Adaptee to the Target interface.
#ifdef CLASS_ADAPTER
// 1. A class adapter uses multiple inheritance to adapt one interface to another.
class Adapter : public Target, private Adaptee
{
public:
virtual void Request() { Adaptee::SpecificRequest(); }
};
#else
// 2. A object adapter relies on object composition.
class Adapter : public Target
{
public:
Adapter() : m_pAdaptee(new Adaptee) { }
~Adapter()
{
if (m_pAdaptee != nullptr)
{
delete m_pAdaptee;
m_pAdaptee = nullptr;
}
}
virtual void Request()
{
m_pAdaptee->SpecificRequest();
}
private:
Adaptee *m_pAdaptee;
};
#endif
// Client
// - collaborates with objects conforming to the Target interface
//
// Collaborations
// - Clients call operations on an Adapter instance. In turn, the adapter
// calls Adaptee operations that carry out the request.
int main()
{
Target *pTargetObj = new Adapter();
pTargetObj->Request();
if (pTargetObj != nullptr)
{
delete pTargetObj;
pTargetObj = nullptr;
}
return 0;
}
/////////////////////////////////////////////////////////////////////////
// 1. The amount of work Adapter does depends on how similar the Target
// interface is to Adaptee's.
// 2. A class adapter uses multiple inheritance to adapt interfaces. The
// key to class adapters is to use one inheritance branch to inherit the
// interface and another branch to inherit the implementation. The usual
// way to make this distinction in C++ is to inherit the interface publicly
// and inherit the implementation privately.
// 3. The object adapter uses object composition to combine classes with
// different interfaces.