Java设计模式——适配器模式(Adapter)
目的:把源类型适配为目标类型,以适应客户端(Client)的需求;此处我们把目标接口的调用方视为客户端
使用场景:需要对类型进行由源类型到目标类型转换的场景中
前置条件:已有客户端
//Client 一个调用目标接口的方法
Class ClientInvoking { static void invoke(TargetInterface target) {
String value = target.getMark();
System.out.println(value);
} }
常用的几种模式
模式一:存在目标接口,且存在已有方法
//目标接口
public interface TargetInterface { public String getMark(); public String getInfo(); }
//已有类及方法
public class ExistClass { public String sayHello() {
return "Hello";
} public String sayWorld() {
return "World";
}
}
我们假设ExistClass返回的字符串正好是我们的客户端需要用到的,但客户端需要的是通过一个TargetInterface类型的对象来获取,因此我们需要想办法对已有类进行适配,使其能够满足客户端的需求;该模式下存在两种应用方案:
方案1.类适配器模式
//适配器
public class ClassAdapter extends ExistClass implements TargetInterface { public int getMark() {
String value = this.sayHello();
return value;
} public int getInfo() {
String value = this.sayWorld();
return value;
} }
//客户端调用
TargetInterface target = new ClassAdapter();
ClientInvoking.invoke(target);
由Java接口的概念可知,ClassAdapter作为TargetInterface的实现类,能够向上转型为TargetInterface类型,适应了客户端的需求。
方案2.对象适配器模式
//适配器
public class ClassAdapter implements TargetInterface { private ExistClass exist; public ClassAdapter(ExistClass existClass) {
this.exist = existClass;
} public int getMark() {
String value = exist.sayHello();
return value;
} public int getInfo() {
String value = exist.sayWorld();
return value;
} }
//客户端调用
TargetInterface target = new ClassAdapter(new ExistClass());
ClientInvoking.invoke(target);
该方案与类适配器模式类似,只是不采用继承而采用持有对象的方式,更加灵活,扩展性更强。
模式二:不存在目标接口,但是存在目标类,且存在已有方法
我们先对前置条件中的客户端进行改造,如下:
Class ClientInvoking {
static void invoke(TargetClass target) {
String value = target.getMark();
System.out.println(value);
}
}
改造后,invoke方法需要一个TargetClass类的对象作为参数;下面是目标类和已有类
//目标类
public class Class { public String getMark() {
return "yes";
} public String getInfo() {
return "no";
} }
//已有类及方法
public class ExistClass { public String sayHello() {
return "Hello";
} public String sayWorld() {
return "World";
}
}
我们假设ExistClass返回的字符串正好是我们的客户端需要用到的,且客户端中需要的TargetClass对象的内容已经过时,因此我们需要相办法对ExistClass进行适配,以适应客户端的需求;
//适配器
public class ClassAdapter extends TargetClass { private ExistClass exist; public ClassAdapter(ExistClass existClass) {
this.exist = existClass;
} public int getMark() {
String value = exist.sayHello();
return value;
} public int getInfo() {
String value = exist.sayWorld();
return value;
} }
//客户端调用
TargetClass target = new ClassAdapter(new ExistClass());
ClientInvoking.invoke(target);
在该种模式下,设计到两个类,且最后要进行向上转型,根据Java的单继承机制,我们只能通过持有对象的形式,即对象适配器模式。
模式三:缺省适配器模式
该模式中,不存在显式的目标类型,而仅有源类型;之所以需要用到这个,往往是因为源类型中提供了太多我们并不需要的东西,我们需要通过适配器模式进行定制化。以WindowListener作为例子讲解:
//WindowListener源码
public interface WindowListener extends EventListener {
public void windowOpened(WindowEvent e);
public void windowClosing(WindowEvent e);
public void windowClosed(WindowEvent e);
...
}
//添加监听器的例子
Frame frame = new Frame();
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) { } @Override
public void windowClosing(WindowEvent e) { } @Override
public void windowClosed(WindowEvent e) { }
...
})
这样的代码,看起来很繁琐;比如说我只需要监听正在关闭的事件,却生成了许多与此无关的模板代码,降低了代码的可读性,鉴于此,我们来做下定制,只监听一个接口;
我们首先提供一个抽象类实现了该接口,并为所有监听器提供空实现;然后再用抽象类的子类重写窗口正在关闭的监听器的实现,代码如下:
//适配器
public abstract ListenerAdapter implements WindowListener {
public void windowOpened(WindowEvent e) {}
public void windowClosing(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
...
}
//重写方法
public class OverrideWindowClosing extends ListenerAdapter { @Override
public void windowClosing(WindowEvent e) {
//TODO
} }
//客户端调用
frame.addWindowListener(new OverrideWindowClosing());
该方式简化了接口,提高了代码可读性。最重要的是,我们实现了对接口的定制,可以只做自己关心的事情。
Java设计模式——适配器模式(Adapter)的更多相关文章
- Java设计模式——适配器模式
JAVA 设计模式 适配器模式 用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器 ...
- 【设计模式】Java设计模式 - 适配器模式
[设计模式]Java设计模式 - 适配器模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一 ...
- JAVA 设计模式 适配器模式
用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口. Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 适配器模式是一种结构型模式. 结构
- 设计模式 - 适配器模式(adapter pattern) 枚举器和迭代器 具体解释
适配器模式(adapter pattern) 枚举器和迭代器 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考适配器模式(adapter patter ...
- 设计模式 - 适配器模式(adapter pattern) 具体解释
适配器模式(adapter pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 适配器模式(adapter pattern): 将一个类的接 ...
- Java设计模式-适配器模式(Adapter)
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式.首先,我们来看看类的适配器模 ...
- Java设计模式 - 适配器模式
概念: 将一个类的接口,转换成客户期望的另一个接口.适配器模式让原来接口不兼容的类可以在一起工作. 解决的问题: 提供类似于中间人的作用:把原本不兼容.不能一起工作的接口组合在一起,使得它们能够在一起 ...
- java设计模式——适配器模式 Java源代码
前言:适配器模式就是把一个类的接口变换成客户端所能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作.通常被用在一个项目需要引用一些开源框架来一起工作时,这些框架的内部都有一 ...
- Java设计模式の适配器模式
定义 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作. 适配器模式的用途 用电器做例子,笔记本电脑的插头一般都是三相的,即除了阳极 ...
随机推荐
- git 本地同步分支数,删除远程已经删除掉的多余分支
git remote show orgin (展示当前本地分支和远程上的分支差异,多余分支后会被标注 use 'git remote prune' to remove.) git remote pr ...
- SELECT 语句
常见表的操作 查看数据库的表 show table 查看表结构 desc 表名 删除表 drop table表 修改表的结构 添加列 alter table 表名 add 列名 ...
- 根据excel表格字段生成sql语句
根据excel表格字段生成sql语句 1.1 前言 根据excel表格字段生成sql语句主要是利用了excel的拼接函数 CONCATENATE .该实例主要以mysql脚本支持.实例需求如下:exc ...
- freemarker导出带图片的word文档
最近做一个关于文档导出功能, 顺便学习了下freemarker,做了个关于导出带图片的word文档,模板并没有写全,只是验证代码的正确性 这只是做一个小功能,故只做了后台代码关于导出的代码,并未与前台 ...
- 安卓开发学习笔记(七):仿写腾讯QQ登录注册界面
这段代码的关键主要是在我们的相对布局以及线性布局上面,我们首先在总体布局里设置为线性布局,然后再在里面设置为相对布局,这是一个十分常见的XML布局模式. 废话不多说,直接上代码:一.activity. ...
- emWin视频播放器,含uCOS-III和FreeRTOS两个版本
第10期:视频播放器配套例子:V6-918_STemWin提高篇实验_视频播放器(RTX版本,仅支持MDK4.74) 例程下载地址: http://forum.armfly.com/forum.php ...
- [Swift]LeetCode347. 前K个高频元素 | Top K Frequent Elements
Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...
- [Swift]LeetCode412. Fizz Buzz
Write a program that outputs the string representation of numbers from 1 to n. But for multiples of ...
- Npoi简单读写Excel
什么是NPOI ? 简而言之,NPOI就是可以在没有Office的情况下对Word或Excel文档进行读写等操作. 使用方式 : 1.准备NPOI的dll文件 下载链接:https://npoi.co ...
- 花点时间顺顺Git(下)
### 进入正文前插个楼,因为vim的操作下面会频繁用到 vim的操作 1.输入i进入插入模式,对上一条commit信息的内容进行修改 2.按下ESC键,退出编辑模式,切换到命令模式. 3.保存修改并 ...