This post implements a relative easy and straight forward pattern in <Head First Design Pattern>:Adapter Pattern. The Adapter Pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. The general procedure is as follows
- Identify the players: the component(s) that want to be accommodated (i.e. the client), and the component that needs to adapt (i.e. the adaptee).
- Identify the interface that the client requires.
- Design a "wrapper" class that can "impedance match" the adaptee to the client.
- The adapter/wrapper class "has a" instance of the adaptee class.
- The adapter/wrapper class "maps" the client interface to the adaptee interface.
- The client uses (is coupled to) the new interface
#include<stdlib.h>
class Duck {
public:
virtual void fly() const = 0;
virtual void quack() const = 0;
};
class MallardDuck : public Duck {
public:
void fly() const {
std::cout << "I'm flying" << std::endl;
}
void quack() const {
std::cout << "Quack" << std::endl;
}
};
class Turkey {
public:
virtual void gobble() const = 0;
virtual void fly() const = 0;
};
class WildTurkey : public Turkey {
public:
void fly() const {
std::cout << "I'm flying a short distance" << std::endl;
}
void gobble() const {
std::cout << "Gobble gobble" << std::endl;
}
};
class DuckAdapter : public Turkey {
private:
Duck* duck;
int random;
DuckAdapter(const DuckAdapter& ); // Disable copy constructor
void operator=(const DuckAdapter& ); // Disable assignment operator
public:
DuckAdapter(Duck* duck_):duck(duck_) {
srand(123);
random = rand() % 5;
if(random == 0) random = 1;
}
void fly() const {
for(int i = 0; i<random; i++ ) {
duck->fly();
}
}
void gobble() const {
duck->quack();
}
~DuckAdapter(){
delete duck;
duck = NULL;
}
};
class TurkeyAdapter : public Duck {
private:
Turkey* turkey;
TurkeyAdapter( const TurkeyAdapter& ); // Disable copy constructor
void operator=( const TurkeyAdapter& ); // Disable assignment operator
public:
TurkeyAdapter(Turkey* turkey_):turkey(turkey_) {}
void fly() const {
for(int i = 0; i < 5; i++ ) {
turkey->fly();
}
}
void quack() const {
turkey->gobble();
}
};
Main function is
#include <iostream>
#include <./duck_geese.hpp>
int main()
{
std::cout << "For duck and duck in turkey disguise: " << std::endl;
MallardDuck* duck = new MallardDuck();
Turkey* duckAdapter = new DuckAdapter(duck);
duck->fly();
duck->quack();
duckAdapter->fly();
duckAdapter->gobble();
std::cout << "For turkey and turkey in duck disguise: " << std::endl;
WildTurkey* turkey = new WildTurkey();
Duck* turkeyAdapter = new TurkeyAdapter(turkey);
turkey->fly();
turkey->gobble();
turkeyAdapter->fly();
turkeyAdapter->quack();
return 0;
}