设计模式(结构型)之适配器模式
适配器模式定义的:将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式分为类适配器模式和对象适配器模式。区别仅在于适配器角色对于被适配角色的适配是通过继承完成的还是通过组合来完成的。由于在java 中不支持多重继承,而且继承有破坏封装之嫌,众多的书中都提倡使用组合来代替继承。对于C++,为了实现类适配器模式,需要通过多继承实现。
一、UML示意图
1)采用继承原有接口类的方式(类适配器模式)
2)采用组合原有接口类的方式(对象适配器模式)
二、组成:
1)采用继承原有接口类的方式(类适配器模式):
a,目标(Target)角色:这就是所期待的接口。注意,对于java,由于这里讨论的是类适配器模式,因此目标不可以是类。
b,源(Adaptee)角色:现有需要适配的接口。
c,适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转换到目标接口。显然这一角色不可以是接口,二必须是具体类。
2)采用组合原有接口类的方式(对象适配器模式):
a, 目标(Target)角色:这就是所期待的接口。注意,对于java,目标可以是具体的或者抽象的类。
b,源(Adaptee)角色:这个角色有一个已存在并使用了的接口,而这个接口是需要我们适配的。
c,适配器(Adapter)角色:这个适配器模式的核心。它将源角色已有的接口转换为目标角色希望的接口。对于java,这一角色必须是具体类。
三、代码实现:
1)采用继承原有接口类的方式(类适配器模式):
JAVA:
ClassAdapter.java:
interface Target{
public void operation1();
public void operation2();
}
class Adaptee {
public void operation2() {
System.out.println("operation2 come from Adaptee");
}
}
class Adapter extends Adaptee implements Target {
@Override
public void operation1() {
// TODO Auto-generated method stub
System.out.println("operation1");
}
}
public class ClassAdapter {
public static void main(String[] args) {
Adapter ad = new Adapter();
ad.operation1();
ad.operation2();
}
}
运行结果:
operation1
operation2 come from Adaptee
C++:
//============================================================================
// Name : ClassAdapter.cpp
// Author : Yan Chao
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include
using namespace std;
class Target {
public:
virtual void operation1() = 0;
virtual void operation2() = 0;
virtual ~Target(){}
};
class Adaptee {
public:
void operation1(){
cout << "operation1 from Adaptee!" << endl;
}
};
class Adapter : public Target, Adaptee {
public:
virtual void operation2() {
cout << "operation2!" << endl;
}
virtual void operation1() {
this->operation1(); // c++中,调用继承的父类的方法,要用this->
}
};
int main() {
Adapter *ad = new Adapter();
ad->operation1();
ad->operation2();
return 0;
}
运行结果:
operation1 from Adaptee!
operation2!
2)采用组合原有接口类的方式(对象适配器模式):
JAVA:
ObjectAdapter.java:
interface Target{
public void operation1();
public void operation2();
}
class Adaptee {
public void operation2() {
System.out.println("operation2 come from Adaptee");
}
}
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void operation1() {
// TODO Auto-generated method stub
System.out.println("operation1");
}
@Override
public void operation2() {
// TODO Auto-generated method stub
adaptee.operation2();
}
}
public class ObjectAdapter {
public static void main(String[] args) {
Adaptee ae = new Adaptee();
Adapter adapter = new Adapter(ae);
adapter.operation1();
adapter.operation2();
}
}
运行结果:
operation1
operation2 come from Adaptee
C++:
//============================================================================
// Name : ObjcetAdapter.cpp
// Author : Yan Chao
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include
using namespace std;
class Target {
public:
virtual void operation1() = 0;
virtual void operation2() = 0;
virtual ~Target(){}
};
class Adaptee {
public:
void operation1(){
cout << "operation1 from Adaptee!" << endl;
}
};
class Adapter : public Target {
public:
Adapter(Adaptee *adaptee){
myAdaptee = adaptee;
}
virtual void operation2() {
cout << "operation2!" << endl;
}
virtual void operation1() {
myAdaptee->operation1();
}
private:
Adaptee *myAdaptee;
};
int main() {
Adaptee *adaptee = new Adaptee();
Adapter *ad = new Adapter(adaptee);
ad->operation1();
ad->operation2();
return 0;
}
运行结果:
operation1 from Adaptee!
operation2!