java之对象适配器
对象的适配器模式
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。对象的适配器模式的静态结构如下图所示。

从上图中可以看出,Adaptee类并没有simpleOperation2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了这个适配器模式是对象的。
从上图可以看出,模式所涉及的角色有:
- 目标(Target)角色:这就是所期待的接口,目标可以是具体的或抽象的类。
- 源(Adaptee)角色:现有需要适配的接口。
- 适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口,显然,这一角色必须是具体类。
对象的适配器模式代码
public interface Target {
/**
* 这是源类也有的方法simpleOperation1
*/
void simpleOperation1();
/**
* 这是源类没有的方法simpleOperation2
*/
void simpleOperation2();
}
上面给出的是目标角色的源代码,这个角色是以一个Java接口的形式实现的。可以看出,这个接口声明了两个方法:simpleOperation1()和simpleOperation2()。而源角色Adapatee是一个具体类,它有一个simpleOperation1()方法,但是没有simpleOperation2()方法,如下面带入清单所示。
public class Adaptee {
/**
* 源类含有方法simpleOperation1
*/
public void simpleOperation1(){};
}
适配器类的源代码如下面代码清单所示。
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
super();
this.adaptee = adaptee;
}
/**
* 源类有方法simpleOperation1
* 因此适配器类直接委派即可
*/
@Override
public void simpleOperation1() {
adaptee.simpleOperation1();
}
/**
* 源类没有方法simpleOperation2
* 因此适配器类补充上这个方法
*/
@Override
public void simpleOperation2() {
//write you code here
}
}
对象的适配器模式的效果:
- 一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。
- 与类的适配器模式相比,要想置换源类的方法就不容易。如果一定要置换掉源类的一个或多个方法,就只好先做一个源类的子类,将源类的方法置换掉,然后再把源类的子类当作真正的源进行适配。
- 虽然想要置换源类的方法不容易,但是要想增加一些新的方法则方便得很,而且新增加的方法可同时适用于所有的源。
总结
适配器模式将现有接口转化为客户类所期望的接口,实现了对现有类的复用,它是一种使用频率非常高的设计模式,在软件开发中得以广泛应用,在Spring等开源框架、驱动程序设计(如JDBC中的数据库驱动程序)中也使用了适配器模式。
** 1. 主要优点**
无论是对象适配器模式还是类适配器模式都具有如下优点:
- 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
- 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。
- 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
具体来说,类适配器模式还有如下优点:
- 由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强。
对象适配器模式还有如下优点:
- 一个对象适配器可以把多个不同的适配者适配到同一个目标;
- 可以适配一个适配者的子类,由于适配器和适配者之间是关联关系,根据“里氏代换原则”,适配者的子类也可通过该适配器进行适配。
** 2. 主要缺点**
类适配器模式的缺点如下:
- 对于Java、C#等不支持多重类继承的语言,一次最多只能适配一个适配者类,不能同时适配多个适配者;
- 适配者类不能为最终类,如在Java中不能为final类,C#中不能为sealed类;
- 在Java、C#等语言中,类适配器模式中的目标抽象类只能为接口,不能为类,其使用有一定的局限性。
对象适配器模式的缺点如下:
- 与类适配器模式相比,要在适配器中置换适配者类的某些方法比较麻烦。如果一定要置换掉适配者类的一个或多个方法,可以先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂。
** 3. 适用场景**
在以下情况下可以考虑使用适配器模式:
- 系统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统的需要,甚至没有这些类的源代码。
- 想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
- (对对象的适配器模式而言)在设计里,需要改变多个已有的子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器类,而这不太实际。
java之对象适配器的更多相关文章
- 适配器模式(Adapter):类适配器、对象适配器
适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口.A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适用场景: 1.已经存在的类的接口 ...
- 规则引擎集成接口(九)Java类对象
Java类对象 右键点击“对象库” —“添加java类对象”,如下图: 弹出窗体,在文本框中输入类的全名“com.flagleader.test.Test”,选择该类型后确定,如下: 显示如下,勾选上 ...
- java类 对象 和构造方法
github地址:https://github.com/lily1010/java_learn/tree/master/dog java中对象和类 java中万物皆对象,比如说动物,里面有猫,狗,鱼等 ...
- java integer对象判断两个数字是否相等
java integer对象判断两个数字是否相等,不一定对 问题发生的背景:javaweb的项目,起先,因为在java中实体类中的int类型在对象初始化之后会给int类型的数据默认赋值为0,这样在很多 ...
- 转载---Java集合对象的深度复制与普通复制
原博文:http://blog.csdn.net/qq_29329775/article/details/49516247 最近在做算法作业时出现了错误,原因是没有弄清楚java集合的深度复制和浅度复 ...
- spring mvc返回json字符串数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable
1.spring mvc返回json数据,只需要返回一个java bean对象就行,只要这个java bean 对象实现了序列化serializeable 2. @RequestMapping(val ...
- [原创]java WEB学习笔记81:Hibernate学习之路--- 对象关系映射文件(.hbm.xml):hibernate-mapping 节点,class节点,id节点(主键生成策略),property节点,在hibernate 中 java类型 与sql类型之间的对应关系,Java 时间和日期类型的映射,Java 大对象类型 的 映射 (了解),映射组成关系
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Gson把json串转换成java实体对象
Gson把json串转换成java实体对象的方法如下: 1.首先导入Gson的jar包,网上可以下载. java实体对象如下: public class Model { private double ...
- net.sf.json在处理json对象转换为普通java实体对象时的问题和解决方案
我使用的net.sf.json是json-lib-2.4-jdk15.jar,把json对象转换为普通java实体对象时候有个问题,josn对象转换为java对象之后,json串里面的那几个小数点的值 ...
随机推荐
- mybatis由浅入深day01_4.7根据用户名称模糊查询用户信息_4.8添加用户((非)自增主键返回)
4.7 根据用户名称模糊查询用户信息 4.7.1 映射文件 使用User.xml,添加根据用户名称模糊查询用户信息的sql语句. 4.7.2 程序代码 控制台: 4.8 添加用户 4.8.1 映射文件 ...
- Effective C++ Item 35 Consider alternatives to virtual functions
考虑你正在为游戏人物设计一个继承体系, 人物有一个函数叫做 healthValue, 他会返回一个整数, 表示人物的健康程度. 由于不同的人物拥有不同的方式计算他们的健康指数, 将 healthVal ...
- swift--动画效果
一.for循环创建4*4个view,然后对立面的所有view进行动画,这里列集中动画的效果: 1,旋转动画 for tile in backgrounds{ //现将数字块大小职位原始尺寸的1/10 ...
- break、continue、return之间的区别与联系
今天在部署程序的时候,监控日志发现这个问题了.return的问题就这么总结哈. 在软件开发过程中,逻辑清晰是非常之重要的. 代码的规范也是非常重要的.往往细节决定成败.在编写代码的时候,一定要理解语言 ...
- 在linux中添加环境变量
首先用命令查看配置了哪些环境变量 env命令查看 编辑环境变量命令 vim ~/.bash_profile Counter_HOME=/home/test/Counterexport Counter ...
- Nginx(二)-- 配置文件之虚拟主机配置
1.配置文件与解释 #user nobody; worker_processes 1; # 设置工作子进程,默认是1个工作子进程,可以修改,一般设置为CPU的总核数 #error_log logs/e ...
- Redis(六)-- SpringMVC整合Redis
一.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...
- 第二篇:一个经典的比喻( 关于TCP连接API )
前言 编程是对现实世界的模拟,网络通信自然也是对现实世界通信的模拟.可以将网络通信中使用的各种API和对现实世界中的各种通信设备进行通讯的操作进行对比以加深理解. 对比 socket() 函数 vs ...
- SecureCRT 详细使用图文教程(按步骤)
一.安装和激活 安装 1.在http://www./softs/55471.html下载相关包激活工具,运行scrt622-x86.exe. 2.进入安装向导程序,默认下一步,直到安装完成既可以. 破 ...
- redis 之初体验(window)
1 下载window版本的redis :https://github.com/MSOpenTech/redis/releases 2 解压压缩包.我的放在了E盘: E:/redis 3 程序,输入cm ...