设计模式学习 - 适配器模式
程序员文章站
2022-06-13 12:32:46
...
适配器模式简介
定义
适配器模式又称之包装模式,将一个类的接口转换成用户所希望的接口,可以使原本两个不相互兼容的类在一起工作。
可以通俗理解为,适配器模式就是把目标理想变成现实的。
UML类结构图
适配器模式分为类适配器模式和对象适配器模式,两者的UML类图有点细微的区别。
类适配器模式
对象适配模式
从上图可以看出,类适配模式与对象适配器区别主要体现在Adapter与Adaptee的关系不同。
- 类适配器模式:是通过继承关系把Adaptee与Adapter连接到一起。
- 对象适配器模式:是以委托代理的方式连接到一起,用户通过对象传递的方式进行关联。
角色介绍:
- Target:目标角色,用户理想中的接口,这里目标接口是YaoMing
- Adaptee:被适配的类,实现情况下的接口,这里被适配的类是JiaoLian
- Adapter:适配转换器,是理想目标实现的方式,是一个具体类,是整个适配器模式的核心。
下面通过简单的例子,再结合UML图就能够很好的理解适配器模式是什么样子。
适配器模式的简单实现
据说,姚明刚刚去NBA打球时,有记者采访姚明说:“在CBA和NBA最大的区别是什么?”,姚明的答案是“在NBA我需要翻译,而在CBA我不需要”,可见姚明刚开始是不懂外语的,在比赛中,怎样听懂明白教练的战术安排,此时就需要找到一个中间人进行翻译,把教练的话翻译成中文,姚明就可以听懂了。
- 姚明希望听到的是中文,就是Target目标接口
- 实际上教练讲的是英文,就是被适配Adaotee类。
- 中间人翻译,把英文翻译成中文的过程,就是Adapter类
代码实现
1、创建用户希望的目标YaoMing接口,姚明希望能听到中文。
/**
*
* @author 13480
* 目标类(用户所期待的样子),
* 姚明希望听到是中文话。
*/
public interface YaoMing {
String getChinese();
}
2、创建一个需被适配的类Adaptee。
/**
*
* @author 13480
* Adaptee类,需要被适配的类
* 需要教练本身讲的是英文,姚明听不懂,这时教练说的话就要被翻译成中文,姚明才能听懂,这就是被适配的类
*/
public class JiaoLian {
//教练战术安排,要求姚明加强防守
public String english(){
return "Yao Ming strengthens defense";
}
}
3、创建中间翻译人Adapter,这里分成类适配器模式和对象适配器模式进行对比。
(1)类适配器模式的Adapter
public class TranslatorAdapter extends JiaoLian implements YaoMing{
@Override
public String getChinese() {
String english = english();
System.out.println("JiaoLian:"+english);
//中间省略……翻译过程 english --> chinese
String chinese="姚明加强防守";
return chinese;
}
}
(2)对象适配器模式的Adapter
public class TranslatorAdapter2 implements YaoMing{
private JiaoLian mJiaoLian;
public void setJiaoLian(JiaoLian mJiaoLian) {
this.mJiaoLian = mJiaoLian;
}
@Override
public String getChinese() {
String english = mJiaoLian.english();
System.out.println("JiaoLian:"+english);
//中间省略……翻译过程 english --> chinese
String chinese="姚明加强防守";
return chinese;
}
}
4、用户端使用
public class AdapterTest {
public static void main(String[] args) {
//类适配器模式使用
TranslatorAdapter translatorAdapter = new TranslatorAdapter();
System.out.println("翻译的结果:"+translatorAdapter.getChinese());
//对象适配器模式使用
JiaoLian jiaoLian = new JiaoLian();
TranslatorAdapter2 translatorAdapter2 = new TranslatorAdapter2();
translatorAdapter2.setJiaoLian(jiaoLian);
System.out.println("翻译的结果:"+translatorAdapter2.getChinese());
}
}
输出结果:
JiaoLian:Yao Ming strengthens defense
翻译的结果:姚明加强防守
从实现中可以看出,对象适配器是对象传递来实现关联的,因此可以适配多个对象,而类适配器则是通过继承来关联的,由于java中只能单继承,所以无法做到动态修改,只能适配一个类;除此之外,适配器类由于继承于被适配器类,会把被适配类的属性方法暴露出来,会造成潜在使用安全问题。因此开发中更多的是选择对象适配器方式实现,更灵活又安全。
使用场景
- 往往在项目后期维护中,旧接口不太符合新需求的要求,而又不想创建新对象来实现,想复用旧接口,此时可以用适配器模式进行包装。
- 需要一个统一的输出接口,而用户端输入又是一个未知的类型。在Android最典型的就是ListView的适配器,适配器暴露getView接口,来满足用户各种各样的样式布局。
上一篇: 设计模式学习——适配器模式