Java设计模式(一) Adapter(适配器)模式及I/O实例引申
来源:互联网 发布:椅子 孩子写作业 知乎 编辑:程序博客网 时间:2024/05/13 11:50
基本概念
适配器模式是一种补救模式,将一个类的接口转换成客户希望的另外一个接口。Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作。是包装模式(对类或者对象进行包装)的一种,分为类适配器和对象适配器,是从实现层面上划分。
这个模式中包含三种角色:
- Target目标角色:该角色定义我们要将原接口转化为何种接口,也就是我们期望得到的接口(方便多态地使用)
- Adaptee源角色:需要利用适配器进行包装的原接口
- Adapter适配器:该模式的核心角色,具有将Adaptee包装为Target的职责
综上,我们能够知道该模式中各个角色的关系:
Adapter改变了Adaptee的接口,使Adaptee和Adapter的基类Target匹配。这样Client就可以把Adaptee当作Target类型来使用。(多态得以实现)
例讲Adapter的具体实现
类适配器的实现
我们规定一个情景,A公司要收购B公司,但是他们有两套接口不是很一致的人员管理系统,如下:
- 首先我们给出A公司的接口和实现类(其实重要的只是接口)
interface MyEmployee{ public String getName(); public void setName(String name); public String getPosition(); public void setPosition( String position ); public String getAddress(); public void setAddress( String address ); public String getAge(); public void setAge( String age );}
实现类如下,给出实现,只是体现适配器能极大程度忽略内部实现细节。
class EmployeeA implements MyEmployee {//实现MyEmployee接口 private String name; private String position; private String address; private String age;//应该注意@override注释的必要性,能检查是否为有效的覆盖 @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } //TODO 同样的getter和setter}
- 然而我们的B公司的提供了完全不同的接口和实现方式(为了简单直接写在一起了…实际上接口和实现分开是有优势的),B公司将所有的信息存在了一个利用键值对对应的map中,好尴尬啊…适配器就应该在这时候出现进行补救。
class EmployeeB{ private Map<String,String> basicInfo; public Map<String, String> getBasicInfo() { return basicInfo; } public void setBasicInfo(Map<String, String> basicInfo) { this.basicInfo = basicInfo; }}
我们采用类适配器来解决这一问题,定义上类适配器应该继承原类,实现目标接口,这样能够达到获得源类的方法,并且采用目标接口的调用形式
class EmployeeAdapter extends EmployeeB implements MyEmployee { @Override public String getName() { return getBasicInfo().get("name"); } @Override public void setName(String name) { Map<String,String> dic = getBasicInfo(); String key = "name"; dic.remove( key); dic.put( key , name ); }}
然后我们就可以利用MyEmployee接口同时操作两个公司的员工,并且可以实现多态需要达到的任何操作。
public class adapterEg { public static void main ( String [] args ){ MyEmployee b = new EmployeeAdapter(); MyEmployee a = new EmployeeA(); //TODO 一系列操作 }}
对象适配器的实现
其实往往现实问题没有我们想象中的那般美好,公司经营出现问题的很多,重组的AB公司开始收购C公司,然而C公司活该倒闭,接口杂乱不堪…..将每个属性独立开来,因为Java不支持多继承(这并不是功能的缺失,而是对好的代码结构的一种保证)
class CName { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}class CAddress{ private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; }}//TODO 诸如此类的重复代码,没必要赘述
我们可以采用委托的方式替代继承的方式,来到适配的效果
class AdapterC implements MyEmployee{ private CName cname; private CAddress address; //TODO 其他的过于赘余,不再多讲 AdapterC(){ cname = new CName(); address = new CAddress(); } @Override public String getName() { return cname.getName(); } @Override public void setName(String name) { cname.setName(name); }
也能够达到适配的效果,是不是很简单!!!!
适配器模式的优点
- 能够让两个设计初期没有考虑公用一个接口的类,能够通过添加适配器补救
- 增加了类的透明性,具体实现委托给了源角色,只提供统一的接口
- 使一些类能够在新的设计中得到复用(可以通过适配解决接口不统一的问题)
- 灵活性好,易拓展的同时也方便删改,因为只需要去掉适配器即可,耦合性低,是良好的设计
适配器模式的适用场景
在系统拓展时,为了使新的设计与旧的设计相适应而采取的模式,它不是为了解决还在处于开发阶段的问题,而是解决正在服役中的项目问题。
同作为包装模式,外观模式(Facade)与适配器模式的区别:
- 在两个模式中都存在既有的类(也就是需要通过包装来适用某些功能的类)
- Facade不需要适用多态行为,而adapter多数情况下是为了适应多态场景,如上述的场景
- 动机上,Facade是为了简化接口,而Adapter尽管也希望接口尽量简单,但是是为了遵循一个已有的接口,即时这样失去了使用一个设计更加简洁的接口的可能。
总结如下表
Java I/O对适配器模式的使用
- 最直接的就是InputStreamReader和OutputStreamWriter就是InputStream和OutputStream针对Reader和Writer接口的适配。
- 比如InputStreamReader实现了Reader接口,并且持有了InputStream的引用(对象适配),通过StreamDecoder类间接持有,因为从byte到char需要编码。
鸡汤
- 技术是为业务服务的,因此业务在日新月异变化的同时,也对技术提出了同样的要求
- 在这种要求下,使用补救模式可以保证我们的系统在生命周期内能够稳定、可靠、健壮的运行,而适配器模式就是这样一个救世主,它通过把非本系统接口的对象包装成本系统可以接收的对象,从而简化了系统大规模变更的风险。
——《设计模式之禅》
0 0
- Java设计模式(一) Adapter(适配器)模式及I/O实例引申
- Java设计模式(二) Decorator(装饰)模式及Java I/O引申
- Java设计模式:Adapter(适配器)
- Java设计模式-----Adapter适配器模式
- java 设计模式之一 适配器模式 adapter
- java设计模式---Adapter适配器模式
- Java设计模式 - Adapter(适配器模式)
- Java设计模式-----Adapter适配器模式
- Java:设计模式之适配器模式Adapter
- Java-设计模式(Adapter适配器模式)
- Java-设计模式(Adapter适配器模式)
- java设计模式之适配器模式Adapter
- JAVA设计模式---adapter(适配器模式)
- Java设计模式--适配器(Adapter)模式
- Java设计模式---适配器模式(Adapter)
- Java设计模式-适配器模式Adapter
- Java设计模式--适配器(Adapter)模式
- Java设计模式----适配器模式(Adapter)
- 多线程(3):线程的状态
- 新学的插件jquery.tablesorter很好用,说说遇到的表格动态添加的数据不能排序的问题
- Android中让TextView显示指定的行数并且多出的部分显示省略号
- 第二条:遇到多个构造器参数时要考虑用构建器
- 使用Jenkins配置自动化构建
- Java设计模式(一) Adapter(适配器)模式及I/O实例引申
- Bootstrap框架个人总结
- 深度学习基本概念
- 关于MediaRecorder.setOutputFile(file)的问题!
- updateViewConstraints和updateConstraints
- 【经典算法】:对于堆排序的理解及其实现
- Kubernetes
- 插入排序
- 【学习笔记】3D图形核心基础精炼版-11:stage3D实战-光照效果和范例工程3