设计模式【6.2】-- 再聊聊适配器模式
这里说的适配器不是通常所说的类适配器,对象适配器,接口适配器,这里实现的是把所有的类进行统一管理的适配器。如需要查找设计模式的三种主要适配器模式,请点击https://blog.csdn.net/Aphysia/article/details/80291916
适配器模式(百度百科):在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
可以这么理解,原来可能两个接口或者两个类不兼容,适配器模式要做的事情就是把它们统一管理,让他们可以一起工作。举个简单的例子:内存卡和笔记本,是不能直接连接工作的,但是我们使用读卡器,相当于适配器,把它们连接起来了。
1.不使用适配器的例子:
- 需求:程序猿的工作是
program()
,教师的工作是teach()
,那么这些不同的职业,具体的工作都是不一样的,这些程序猿program()方法内容也可能是不一样的,比如说京东,阿里,腾讯等等,教师也是一样的,不同学校的老师工作内容也各异。所以我们必须定义接口,不同工作内容的也可以通过实现自己的接口去实现。
代码结果如下:
IProgramer.class(程序猿撸代码的接口)
package com.noadapter;
public interface IProgramer {
public void program();
}
Programer.class(程序猿的类,实现了撸代码的接口)
package com.noadapter;
public class Programer implements IProgramer {
@Override
public void program() {
System.out.println("我是一个优秀的程序猿,我整天撸代码");
}
}
下面的教师接口以及实现教师的类也和上面程序猿的一样:
ITeacher.class(教师教书接口):
package com.noadapter;
public interface ITeacher {
public void teach();
}
Teacher.class(实现了教书的教师类):
package com.noadapter;
public class Teacher implements ITeacher {
@Override
public void teach() {
System.out.println("我是教师,我教育祖国的花朵");
}
}
MyTest.class 测试类:
package com.noadapter;
public class MyTest {
public static void main(String []args){
ITeacher teacher = new Teacher();
IProgramer programer = new Programer();
//必须挨个访问他们的方法
teacher.teach();
programer.program();
}
}
运行结果:
理解:如果不是用适配器模糊,那么我们要定义出所有的工种对象(程序猿,教师等等),还要为他们实现各自的接口,然后对他们的方法进行调用,这样有多少个工种,就要写多少个方法调用,比较麻烦。
2.只定义一个适配器实现类
在前面的基础上修改,增加了IWorkAdapter.class
以及它的实现类WorkerAdapter.class
,以及更改了测试方法,其他的都没有改变,代码结构如下:
增加的IWorkAdapter.class
(适配器的接口):
public interface IWorkAdapter {
//参数之所以是Object,是因为要兼容所有的工种对象
public void work(Object worker);
}
增加的WorkAdapter.class
(适配器的类):
public class WorkAdaper implements IWorkAdapter {
@Override
public void work(Object worker) {
if(worker instanceof IProgramer){
((IProgramer) worker).program();
}
if(worker instanceof ITeacher){
((ITeacher) worker).teach();
}
}
}
更改过的测试类MyTest.class
:
public class MyTest {
public static void main(String []args){
ITeacher teacher = new Teacher();
IProgramer programer = new Programer();
//把两个工种放到对象数组
Object[] workers = {teacher,programer};
//定义一个适配器
IWorkAdapter adapter = new WorkAdaper();
//适配器遍历对象
for(Object worker:workers){
adapter.work(worker);
}
}
}
结果依然不变:
分析:只写一个适配器,功能上就像是把接口集中到一起,在中间加了一层,这一层把调用不同工种(程序猿,教师)之间的差异屏蔽掉了,这样也达到了解耦合的作用。
3.多个适配器的模式
也就是为每一个工种都定义一个适配器(在一个适配器的基础上进行修改)
修改 IWorkAdapter.class
public interface IWorkAdapter {
//参数之所以是Object,是因为要兼容所有的工种对象
public void work(Object worker);
//判断当前的适配器是否支持指定的工种对象
boolean supports(Object worker);
}
定义一个TeacherAdapter.class
public class TeacherAdapter implements IWorkAdapter{
@Override
public void work(Object worker) {
((ITeacher)worker).teach();
}
@Override
public boolean supports(Object worker) {
return (worker instanceof ITeacher);
}
}
定义一个ProgrammerAdapter.class
public class ProgrammerAdapter implements IWorkAdapter{
@Override
public void work(Object worker) {
((IProgramer)worker).program();
}
@Override
public boolean supports(Object worker) {
return (worker instanceof IProgramer);
}
}
测试类(Test.class
):
public class MyTest {
public static void main(String []args){
ITeacher teacher = new Teacher();
IProgramer programer = new Programer();
//把两个工种放到对象数组
Object[] workers = {teacher,programer};
//适配器遍历对象
for(Object worker:workers){
IWorkAdapter adapter = getAdapter(worker);
adapter.work(worker);
}
}
public static IWorkAdapter getAdapter(Object object){
IWorkAdapter teacherAdapter = new TeacherAdapter();
IWorkAdapter programmerAdapter = new ProgrammerAdapter();
IWorkAdapter[] adapters = {teacherAdapter,programmerAdapter};
for(IWorkAdapter adapter:adapters){
if(adapter.supports(object)){
return adapter;
}
}
return null;
}
}
个人理解:其实多个适配器的根本是去获取支持该对象的适配器,通过该适配器来使用这个对象。