适配器
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作,适配器分为类适配器和对象适配器,考虑到”组合优于集成”的思想,这里以对象适配器为例进行说明。
实例
main.cc:
/*
design_pattern:"adapter"
*/
#include "power_runner.h"
#include <windows.h>
int main(){
Runner *runner = new Runner();
runner->TrainingMethod();
MuscleTraining *muscle_training = new MuscleTraining();
Runner *power_runner = new PowerRunner(muscle_training);
power_runner->TrainingMethod();
//clear
delete runner;
delete muscle_training;
delete power_runner;
system("Pause");
return 0;
}
Runner:
//runner.h
#ifndef HELENDP_SOURCE_RUNNER_H_
#define HELENDP_SOURCE_RUNNER_H_
class Runner{
public:
Runner();
virtual ~Runner();
virtual void TrainingMethod();
};
#endif
//runner.cc
#include "runner.h"
#include <iostream>
using namespace std;
Runner::Runner(){
}
Runner::~Runner(){
}
void Runner::TrainingMethod(){
cout << "Runner:5 minutes per kilometer running,keep 1 hours!" << endl;
}
PowerRunner:
//power_runner.h
#ifndef HELENDP_SOURCE_POWER_RUNNER_H_
#define HELENDP_SOURCE_POWER_RUNNER_H_
#include "muscle_training.h"
#include "runner.h"
class PowerRunner:public Runner{
public:
PowerRunner(MuscleTraining* muscle_training);
~PowerRunner();
void TrainingMethod();
private:
MuscleTraining *muscle_training_;
};
#endif
//power_runner.cc
#include "power_runner.h"
#include <iostream>
using namespace std;
PowerRunner::PowerRunner(MuscleTraining * muscle_training){
muscle_training_ = muscle_training;
}
PowerRunner::~PowerRunner(){
}
void PowerRunner::TrainingMethod(){
muscle_training_->MuscleTrainingMethod();
}
MuscleTraining:
//muscle_training.h
#ifndef HELENDP_SOURCE_MUSCLE_TRAINING_H_
#define HELENDP_SOURCE_MUSCLE_TRAINING_H_
class MuscleTraining{
public:
MuscleTraining();
virtual ~MuscleTraining();
void MuscleTrainingMethod();
};
#endif
//muscle_training.cc
#include "muscle_training.h"
#include <iostream>
using namespace std;
MuscleTraining::MuscleTraining(){
}
MuscleTraining::~MuscleTraining(){
}
void MuscleTraining::MuscleTrainingMethod(){
cout << "MuscleTraining:3 minutes per kilometer running,keep 10 minute." << endl;
cout << "MuscleTraining:have a rest." << endl;
cout << "MuscleTraining:5 minutes Squat." << endl;
cout << "MuscleTraining:30 times push-ups." << endl;
cout << "MuscleTraining:have a rest." << endl;
cout << "MuscleTraining:3 minutes per kilometer running,keep 10 minute." << endl;
}
代码和UML图(EA)工程文件,最后会整理打包上传.
UML类图
结构
- Target(Runner):目标抽象类
- Adapter(PowerRunner):适配器类
- Adaptee(MuscleTraining):适配者类
优点
- 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码.
- 增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性.
- 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”.
- 一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口.
缺点
- 与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂