定义
适配器模式的定义:将某个类的接口转换为接口客户所需类型,适配器模式解决的问题是:使得原本由于接口不兼容而不能一起工作、不能统一管理的那些类可以一起工作、可以进行同意管理。
举例实现
这里有教师接口ITeacher、程序员接口IProgrammer,分别用于定义他们各自工种的具体工作。然后定义深圳大学的教师SZUTeacher、腾讯的程序
员TcProgrammer。这些不同的工种所作的工作都各自不同,无法进行统一管理,协同工作。我们要做的是将这些不同工种的工作内容全部输出。
ITeacher接口
1
2
3
4
5public interface ITeacher {
void teach();
}
IProgrammer接口
1
2
3
4
5public interface IProgrammer {
void code();
}
SZUTeacher实现类
1
2
3
4
5
6
7
8
9
10
11public class SZUTeacher implements ITeacher {
public void teach() {
System.out.println("教离散数学!");;
}
}
TcProgrammer实现类
1
2
3
4
5
6
7
8
9
10
11public class TcProgrammer implements IProgrammer {
public void code() {
System.out.println("编php程序!");;
}
}
不使用适配器模式
不使用适配器模式,调用者需要定义出所有工作的对象,然后逐个对象调用自己的工作方法。
1
2
3
4
5
6
7
8
9public class Test1 {
public static void main(String[] args) {
ITeacher teacher = new SZUTeacher();
IProgrammer programmer = new TcProgrammer();
//逐个对象调用自己的工作方法
teacher.teach();
programmer.code();
}
}
只定义一个适配器实现类
这种方式类似与多功能充电器,一个电源插头上接着多种类型的充电接口。用户使用充电器充电时,需要使用电器接口与多功能充电器的充电插口逐个对比,接口匹配则可以开始
充电。
适配器接口
1
2
3
4
5
6
7public interface IWorkerAdapter {
//为了兼容所有工种员工,这里的参数必须是Object类型
void work(Object worker);
}
单个适配器实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class WorkerAdapter implements IWorkerAdapter {
public void work(Object worker) {
if(worker instanceof ITeacher){
((ITeacher) worker).teach();
}
if(worker instanceof IProgrammer){
((IProgrammer) worker).code();
}
}
}调用者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class Test2 {
public static void main(String[] args) {
ITeacher teacher = new SZUTeacher();
IProgrammer programmer = new TcProgrammer();
Object[] workers = {teacher, programmer};
IWorkerAdapter workerAdapter = new WorkerAdapter();
for(Object worker:workers){
workerAdapter.work(worker);
}
}
}
为每一个工种定义一个适配器
为每一个工种定义一个适配器
适配器接口
1
2
3
4
5
6
7
8
9public interface IWorkerAdapter2 {
void work(Object worker);
//判断当前适配器是否支持指定工种对象
boolean supprots(Object worker);
}
Teacher适配器实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class TeacherAdapter implements IWorkerAdapter2 {
public void work(Object worker) {
((ITeacher)worker).teach();
}
public boolean supprots(Object worker) {
return (worker instanceof ITeacher);
}
}Programmer适配器实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class ProgrammerAdapter implements IWorkerAdapter2 {
public void work(Object worker) {
((IProgrammer)worker).code();
}
public boolean supprots(Object worker) {
return (worker instanceof IProgrammer);
}
}调用者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35public class Test3 {
public static void main(String[] args) {
ITeacher teacher = new SZUTeacher();
IProgrammer programmer = new TcProgrammer();
Object[] workers = {teacher, programmer};
for(Object worker:workers){
IWorkerAdapter2 adapter = getAdapter(worker);
adapter.work(worker);
}
}
private static IWorkerAdapter2 getAdapter(Object worker) {
IWorkerAdapter2 teacherAdapter = new TeacherAdapter();
IWorkerAdapter2 programmerAdapter = new ProgrammerAdapter();
//获取所有工种适配器
IWorkerAdapter2[] allAdapter = {teacherAdapter, programmerAdapter};
//遍历每一个适配器,尝试哪一个适配器是对应工种
for(IWorkerAdapter2 adapter:allAdapter){
if(adapter.supprots(worker)){
return adapter;
}
}
return null;
}
}
补充:缺省适配器模式
- 缺省适配器模式是由适配器模式简化而来,省略了适配器模式中目标接口,也就是源接口和目标接口相同,原接口为接口,目标接口为类
- 典型的缺省适配器模式是JavaEE规范中的Servlet接口与GenericServlet抽象类
Servlet接口中包含五个抽象方法,而其中的service()方法才是用于实现业务逻辑的、必须要实现的方法,另外四个方法一般都是空实现,或简单实现
GenericServlet抽象类实现了Servlet接口的service()方法以外的另外四个方法,所以自定义的Servlet只需要继承GenericServlet抽象类,实现service()方法即可,无需再实现Servlet接口。