设计模式之(七)适配器模式(Adapter)
作为一个码农,天天都要面对电脑。知道电脑一直在不停的升级换代。电脑的很多零件接口也不断的变化。如果你曾经花巨资采购的一台电脑在使用一段时间后,发现硬盘空间不够使用,需要加一块硬盘,在加的时候才发现新硬盘和电源线插口不匹配。这时候,网络硬件维护人员的同事,给了你一根转换线,一头是旧的串行接口,一头是新的并行接口。通过这个转换线,完美的解决了老电源上和新的硬盘之间的不匹配问题。这里的转换线担任的就是功能就是适配器模式要解决的问题。
通过上面生活中例子,进一步分析,适配器模式就是解决两个事物,在需要对接的时候,发现两者之间是有些冲突的,不能完美的对接起来。为了解决这个问题,就加入一个第三方事物,来解决两者不匹配问题。通过这个思路咱们看看这个定义:
将一个类的接口转换成客户客户希望的另外一个接口,适配器模式使得原来由于接口不兼容问题不能再一起对接的那些类可以在一起工作。
通过上面的介绍了解了适配器模式解决的问题场景,下面我们就举个例子更清晰的熟悉适配器模式。
软件公司开内部会议,需要小王和小李演示新功能,他们都解决了公司一个久未攻克的问题,一但老总认可了,会有一笔不菲的奖金。公司准备了一台是 VGA 接口的投影仪。实现如下:
//VGA投影仪
public class Projector { public String myself = "VGA"; public String toString(){
return myself;
}
}
小王开始演示了,他的电脑笔记本正好有一个 VGA 接口。实现如下:
// VGA接头的接口
public interface VGAInterface { public void VGAwork(String chat); } public class VGAInterfaceImpl implements VGAInterface {
private String thisObject = "VGA 接口";
@Override
public void VGAwork(String chat) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
if(thisObject.contains(chat)){
System.out.println("我是 VGA 接口,插入的是:"+chat + ",匹配");
}
else
{
System.out.println("我是 VGA 接口,插入的是:"+chat + ",不匹配");
}
}
}
电脑连接上投影仪
public class UseProjector {
public static void main(String[] args) {
Projector projector = new Projector();
VGAInterface vga = new VGAInterfaceImpl();
String cht = projector.toString();
vga.VGAwork(cht);
}
}
/***********************************************************/
控制台:我是 VGA 接口,插入的是:VGA,匹配
小王链接上了投影仪,顺利进行了演示,老总非常认可,一笔奖金就要到手,小王心里爽歪歪。
接下来轮到小李进行演示了,在连接投影仪的时候才发现自己电脑上只有 HDMI 接口, HDMI 接口 如下
public interface HDMIInterface {
public void HDMIwork(String Chat);
}
public class HDMIInterfaceImpl implements HDMIInterface{
private String thisObject = "HDMI 接口";
@Override
public void HDMIwork(String chat) {
// TODO Auto-generated method stub
if(thisObject.contains(chat)){
System.out.println("我是 HDMI 接口,插入的是:"+chat + ",匹配");
}
else
{
System.out.println("我是 HDMI 接口,插入的是:"+chat + ",不匹配");
}
}
}
小李电脑和投影仪匹配结构是:
public class UseProjector {
public static void main(String[] args) {
Projector projector = new Projector();
//VGAInterface vga = new VGAInterfaceImpl();
HDMIInterface hdmi= new HDMIInterfaceImpl();
String cht = projector.toString();
hdmi.HDMIwork(cht);
}
}
/******************************************/
我是 HDMI 接口,插入的是:VGA,不匹配
没法连接上投影仪。小李顿时一脑门大汗,老总那么忙,今天不能演示的话,以后变数太大了。正当小李绝望之际,组长递过来一根转行线,可以把 HDMI 接口转换成 VGA 接口。用代码实现如下
//转换线 适配器类
public class Adapter extends VGAInterfaceImpl implements HDMIInterface { // HDMI 接口转换成 VGA
@Override
public void HDMIwork(String chat) {
VGAwork(chat);
}
}
小李顿时喜出望外,通过转换线,进行连接投影仪
public class UseProjector {
public static void main(String[] args) {
Projector projector = new Projector();
//VGAInterface vga = new VGAInterfaceImpl();
//HDMIInterface hdmi= new HDMIInterfaceImpl();
Adapter adapter = new Adapter();
String cht = projector.toString();
adapter.HDMIwork(cht);
}
}
/************************************************/
我是 VGA 接口,插入的是:VGA,匹配
小李看到结果匹配,高兴一蹦多高,终于可以顺利演示了。
简单总结
上面这个例子就是典型的使用适配器解决了问题的例子,问题就是 投影器的 VGA 接口和 小李电脑的HDMI 接口不匹配的问题,通过用适配器模式来解决了这个问题。可以清晰的很出来,适配器模式有一些特点:
1、实在系统扩展过程或者添加的,不是在系统开发过程中设计的。
2、可以在系统扩展后,尽最大可能复用原来的代码
3、一个系统如果使用适配器模式太多,就会造成混乱。
适配器实现方式
适配器的实现方式有两种:类适配器、对象适配器。
类适配器:继承被适配的对象的类,然后实现需要适配成目标类的接口 。被适配对象类 : Adaptee,适配目标的对象的接口:Target。
public class Adapter extends Adaptee implements Target{
public void work(){
Adaptee_work();
}
}
对象适配器:实现需要适配成目标类的接口 。被适配的类当成一个属性。实现如下
public class Adapter implements Target{
// 被适配类
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
public void work(){
adaptee.Adaptee_work();
}
}
对象适配器和类适配器的区别就是:对象适配器可以适配多个类,而类适配器只能适配继承的那个类。而类适配器则可以部分重定义 被适配类的 部分行为。
双向适配器
双适配器,那就那上面的例子来说。HDMI 接口可以转换成 VGA口,那么肯定也可以把 VGA 口转换成为 HDMI 口。在适配类中实现了两者的相互转换,就是双向适配器。
例子上面的例子中,如果在显示前,VGA 接口的投影仪换了,换成了 HDMI 接口的投影仪,那么就需要把 VGA 接口转换成 HDMI 了,再考虑上面那种情况,这就是使用到双向适配器的地方了。下面来完善下代码
//上面的例子演进的双适配器
public class TwoAdapter implements VGAInterface,HDMIInterface { public TwoAdapter(VGAInterfaceImpl VGA){
this.VGA = VGA;
} public TwoAdapter(HDMIInterfaceImpl HDMI){
this.HDMI = HDMI;
} private VGAInterfaceImpl VGA; private HDMIInterface HDMI; // HDMI 转化 VGA
@Override
public void HDMIwork(String chat) {
// TODO Auto-generated method stub
VGA.VGAwork(chat);
}
// VGA 转化 HDMI
@Override
public void VGAwork(String chat) {
// TODO Auto-generated method stub
HDMI.HDMIwork(chat);
}
}
双向适配器用的是对象适配器,也就是利用了对象适配器可以匹配多个 Adatee 的优势来完成的。
小结
适配器模式的适用范围是扩展或对接系统接口,而且是在有冲突不能再一起完好对接起来时候用到的。而不是在系统开发设计之初用到的模式。现实方式包括:对象适配器、类适配器、双向适配器,其实双向适配器是对象适配器的一种。
说了这么多,总结起来适配器的本质就是:转换匹配,复用功能。
设计模式之(七)适配器模式(Adapter)的更多相关文章
- 设计模式 结构型 - 适配器模式 Adapter
Adapter(适配器模式) ---- 加个“适配器”以便于复用 将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 应用场景 如果 ...
- 设计模式系列之适配器模式(Adapter Pattern)——不兼容结构的协调
模式概述 模式定义 模式结构图 模式伪代码 类适配器,双向适配器,缺省适配器 类适配器 双向适配器 缺省适配器 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 主要优点 主要缺点 适 ...
- 设计模式(七)Adapter Pattern适配器模式
适用场景:旧系统的改造升级 实际场景:java.io.InputStreamReader(InputStream)等 1.一个被适配的类 package com.littlepage.AdapterP ...
- IOS设计模式浅析之适配器模式(Adapter)
引言 在项目开发中,有时候会遇到这样的一种情景:需要使用以前开发的“一些现存的对象”,但是新环境中要求的接口是这些现存对象所不满足的.怎样应对这种迁移的需求?使得可以复用这些对象,以满足新的应用环境, ...
- 《JAVA设计模式》之适配器模式(Adapter)
在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能 ...
- 设计模式(五)适配器模式Adapter(结构型)
设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...
- 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...
- 【设计模式】适配器模式 Adapter Pattern
适配器模式在软件开发界使用及其广泛,在工业界,现实中也是屡见不鲜.比如手机充电器,笔记本充电器,广播接收器,电视接收器等等.都是适配器. 适配器主要作用是让本来不兼容的两个事物兼容和谐的一起工作.比如 ...
- 8.3 GOF设计模式二: 适配器模式 Adapter
GOF设计模式二: 适配器模式 Adapter 为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式 SingleTon的三个关键点 ...
- 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)
怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...
随机推荐
- C++编译错误 --- 成员函数定义在 .h 文件中出现重定义错误(Error LNK 2005)
今天写了一个简单的类,定义在 .h 文件中, 类很简单就将其成员函数定义在了一起(class类后面).运行的时候出现了如下图所示的编译错误(error LNK2005) 查资料,大部分都是说需要加上 ...
- 201871010109-胡欢欢《面向对象程序设计(java)》第十周学习总结
201871010109-胡欢欢<面向对象程序设计(java)>第十周学习总结 博文正文开头: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu- ...
- vs解决方案文件出错
问题描述: 电脑死机,重启电脑后打开解决方案,提示“选择的文件不是有效的解决方案文件” 解决方案: 1. 先用记事本打开这个解决方案查看下,发现其中内容变成空白了? 2. 打开项目中的xxxx.vcx ...
- leetcode209. 长度最小的子数组
双指针滑动窗口解法,时间复杂度O(N). 滑动窗口,想象一下,在一个坐标上存在两个指针begin 和i ,begin 代表滑窗的左边框,i代表滑窗的右边框.两者通过分别向右滑动,前者能使窗口之间的和减 ...
- 怎么删除STL容器的元素
在STL容器有顺序容器和关联容器两种. 顺序容器删除元素的方法有两种: 1.c.erase(p) 从c中删除迭代器p指定的元素.p必须指向c中一个真实元素,不能等于c.end().返回一个指向p之后元 ...
- Web协议详解与抓包实战:HTTP1协议-内容协商是怎样进行的(8)
一.内容协商的两种方式 每个 URI 指向的资源可以是任何事物,可以有多种不同的表述,例如一份文档可以有不同语言的翻译.不同的媒体格式.可以针对不同的浏览器提供不同的压缩编码等 二.Proactive ...
- [LeetCode] 343. Integer Break 整数拆分
Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...
- DVWA File Upload 通关教程
File Upload,即文件上传.文件上传漏洞通常是由于对上传文件的类型.内容没有进行严格的过滤.检查,使得攻击者可以通过上传木马获取服务器的webshell权限,因此文件上传漏洞带来的危害常常是毁 ...
- oracle --工具 ODU
一,什么是ODU ODU全称为Oracle Data ba se Unloader ,是用于Oracle 数据库紧急恢复的软件,在各种原因 造成的数据库不能打开或数据删除后没有备份时,使用ODU抢救数 ...
- 主流chatbot机器人调研
wit.ai api.ai microsoft bot frameword rasa pydial 问答系统 语义匹配 语义表示式匹配与交互式匹配.语义表示式匹配是将用户query与候选query分别 ...