今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一遍),我在北京向各位问好。老规矩,首先和各位谈谈适配器模式到底是个什么样的设计思想,而且在实际开发中又是如何应用的。

那些官方的概念我就不在这儿粘贴了,请各位自己想想办法。所谓适配器模式,按我意思说吧,其实它的目的就想达到新老兼容,使把原本不能放在一块工作的类或对象能够让它们同时使用起来,举个例子:比如拿一个互联网产品它的升级换代过程来说吧,如果我们想升级一个产品后不仅能正常使用新开发接口的功能,而且还能保证原来接口的功能依然能正常调用,那么就必须考虑到兼容老接口的问题,这时我们设计的时候可以采用"适配器模式"就可以做到。再比如:有一位阿富汗女子在环游世界,假设她到中国爬长城顺便买了一个手机充电器,完事后接着打算去德国柏林找一个男朋友,可是到了德国她想给她的手机充电,但是问题来了,德国插座的插头只能是2个圆头插头,但是她买的充电器的插头是3个扁平得插头,所以无法使用,这时她不得不在网上订购一个电源转换头才能充电,到这儿我们就能正大光明的引出我们的"适配器设计模式"了,正因为有了它的出现,这些问题才得以解决,而且还让阿富汗女子正常充上电(哈哈哈,纯属虚构望各位不要嘲笑我,我只不过是想给自己找点乐趣能够如愿以偿地学完适配器模式罢了)。

好了,我也不多扯了,直接上码,因为设计模式这块不是说你敲敲代码就能学会的,必须自己悟,希望我的总结能帮助各位更快的切入进去,更好的掌握适配器设计模式,再声明一次,我文章中的案例都是本人虚构的,如有不妥,请勿谩骂。

【案例一】:

项目的更新升级,假设对项目中获取用户信息的功能进行了改造,原来是通过主键获取用户信息,但是升级之后是通过主键和用户账号也能获取到用户信息,但是能够保证新功能和老功能都正常调用,这里我们可以通过适配器模式来设计,达到该需求。

新开发的接口和原来的接口:

 /**
* 旧接口
*/
interface OldService{
//根据主键获取用户信息
Map<String,Object> getUserInfo(String Id);
}
/**
* 旧接口实现类
*/
class OldServiceImpl implements OldService{
//根据主键获取用户信息
@Override
public Map<String,Object> getUserInfo(String Id) {
HashMap<String,Object> userInfo = new HashMap<>();
userInfo.put("id", Id);
return userInfo;
}
} /**
* 新接口
*/
interface NewService{
//根据主键和账号获取用户信息
Map<String,Object> getUserInfo(String Id,String account);
}
/**
* 新接口实现类
*/
class NewServiceImpl implements NewService{
@Override
public Map<String,Object> getUserInfo(String Id, String account) {
HashMap<String,Object> userInfo = new HashMap<>();
userInfo.put("id", Id);
userInfo.put("account", account);
return userInfo;
}
}

为了能够兼容新老接口同时使用,则通过适配器模式来设计一个适配器类,该适配器类需要实现新接口,因为项目已经开发了新接口,我们不可能再去使用旧接口的功能,其次在适配器类中声明一个老接口的实例,目的是能够兼容老接口中的方法。

 /**
* 接口适配器,兼容新老接口的功能都能正常调用
*/
class InterfaceAdapter implements NewService{ //既然开发了新接口,就必须使用新接口的功能,实现新接口 //该适配器是针对为了能够兼容老接口正常使用,则在创建适配器对象时必须传入一个旧接口的实现类对象
private OldService oldService;
public InterfaceAdapter(OldService oldService) {
this.oldService = oldService;
} //经过适配器的兼容,就能通过适配器来正常调用旧接口的功能
@Override
public Map<String, Object> getUserInfo(String Id, String account) {
System.out.println("升级后兼容旧接口");
return oldService.getUserInfo(Id);
}
}

最后通过测试,不管是新接口还是老接口,还是你想调用新接口时达到老接口的功能都没问题,适配器模式都帮你解决了这些问题。

 public class AdapterUpgrade {

     public static void main(String[] args) {
//使用旧接口功能
OldService old = new OldServiceImpl();
Map<String, Object> oldMap = old.getUserInfo("7758520");
System.out.println("旧接口功能:"+oldMap); //使用新接口功能
NewService nw = new NewServiceImpl();
Map<String, Object> newMap = nw.getUserInfo("7758520", "18513032646");
System.out.println("新接口功能:"+newMap); //通过适配器,升级后依然兼容旧接口的功能
InterfaceAdapter adapter = new InterfaceAdapter(old);
oldMap = adapter.getUserInfo("7758820", "18513032646");
System.out.println(oldMap);
}
}

【案例二】:

就是阿富汗女子环游世界,在不同的国家遇到充电的问题,适配器模式也能帮你解决了,设计思想还是不变,只是看你怎么理解了,设计模式这东西吧,看是看不来的,看多了只会浮躁我今天早上刚入手时,看了半天理论找了半天例子,一头雾水,一个Demo下来,详细斟酌了一会儿感觉到模式还是模式啊,自有它的强大之处,不说了,还是看码吧。

 /**
* 适配器模式
* 需求:一位阿富汗女子环游世界,首先她到中国爬长城顺便买了一个手机充电器给手机充电,接着打算去德国柏林找一个男朋友,可是到了德国她想给手机充电,
* 但是问题来了,在德国插座的插头只能是2个圆头插头,但是中国充电器的插头是2/3个扁平插头,所以无法使用。
*/ /**
* 测试
*/
public class Adapter {
public static void main(String[] args) {
//在德国使用德国充电器进行充电
DBSocketInterface dbSocket = new DBSocket();
dbSocket.DBCharge(); //在中国使用中国充电器进行充电
GBSocketInterface gbSocket = new GBSocket();
gbSocket.GBCharge(); //在德国使用中国充电器进行充电
SocketAdapter adapter = new SocketAdapter(gbSocket);
adapter.DBCharge();
}
} /**
* 手机电源适配器,为了能够让阿富汗女子在德国正常使用中国的手机充电器。
*/
class SocketAdapter implements DBSocketInterface{ //既然来到德国,就必须使用德国插座充电,实现德国插座接口 //因为该适配器是针对中国插座的,所以在创建适配器对象时必须传入中国插座接口的实现类对象
private GBSocketInterface gbSocket; //中国插座接口
public SocketAdapter(GBSocketInterface gbSocket) {
this.gbSocket = gbSocket;
} //经过适配器的转换,中国的充电器就可以在德国的插座上正常充电了
@Override
public void DBCharge() {
System.out.println("在德国,经过电源适配器转换*****");
gbSocket.GBCharge();
} } /**
* 德国插座(2个圆头的插头)
*/
interface DBSocketInterface{
//德国插座充电
void DBCharge();
}
/**
* 使用德国插座给手机充电
*/
class DBSocket implements DBSocketInterface{
@Override
public void DBCharge() {
System.out.println("2个圆头插头充电");
}
} /**
* 中国插座(2/3个扁平的插头)
*/
interface GBSocketInterface{
//中国插座充电
void GBCharge();
}
/**
* 使用中国插座给手机充电
*/
class GBSocket implements GBSocketInterface{
@Override
public void GBCharge() {
System.out.println("2/3个扁平插头充电");
}
}

还是那句话,目标还是目标,23种设计模式的学习一直在路上。

Java设计模式之适配器模式(项目升级案例)的更多相关文章

  1. java设计模式5——适配器模式

    java设计模式5--适配器模式 1.结构型模式介绍 1.1.作用 从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题. 分类: 适配器模式 代理模式 桥接模式 装饰模式 组合模式 ...

  2. Java设计模式之适配器设计模式(项目升级案例)

    今天是我学习到Java设计模式中的第三个设计模式了,但是天气又开始变得狂热起来,对于我这个凉爽惯了的青藏人来说,又是非常闹心的一件事儿,好了不管怎么样,目标还是目标(争取把23种Java设计模式接触一 ...

  3. Java设计模式----初识适配器模式

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  4. Java设计模式之适配器模式(Adapter)

    转载:<JAVA与模式>之适配器模式 这个总结的挺好的,为了加深印象,我自己再尝试总结一下 1.定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法 ...

  5. Java设计模式之四 ----- 适配器模式和桥接模式

    前言 在上一篇中我们学习了创建型模式的建造者模式和原型模式.本篇则来学习下结构型模式的适配器模式和桥接模式. 适配器模式 简介 适配器模式是作为两个不兼容的接口之间的桥梁.这种类型的设计模式属于结构型 ...

  6. Java设计模式应用——适配器模式

    性能监控系统中,存在告警模块和报表模块,告警结果和报表结果都需要导出. 由于告警开发进度较快,已经实现了excel导出.csv导出.zip导出功能,现在报表需要excel导出.csv导出.pdf导出功 ...

  7. Java设计模式中适配器模式的实现方法

    在Java开发中,我们常常需要用到Java接口型模式中的适配器模式,那适配器设计模式到底是什么模式呢? 适配器模式(Adapter)就是把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹 ...

  8. 夜话JAVA设计模式之适配器模式(adapter pattern)

    适配器模式:将一个类的接口,转换成客户期望的另一个接口,让不兼容的接口变成兼容. 1.类适配器模式:通过多重继承来实现适配器功能.多重继承就是先继承要转换的实现类,再实现被转换的接口. 2.对象适配器 ...

  9. 指方画圆之Java设计模式:适配器模式

    目录 应用场景 适配器模式 定义 意图 主要解决问题 何时使用 优缺点 指鹿为马VS指方为圆 指鹿为马 指方为圆 应用场景 使用者依赖的接口与提供者的接口不匹配时,就加一层适配,而不修改两端的代码 生 ...

随机推荐

  1. 同是办公软件,wps和office有什么区别?

    今天完美小编为大家带来的是wps和office有什么区别教程,那么到底有什么区别呢?相信很多朋友都模棱两可,说不出所以然,看看下面的教程,相信你会选择更适合你的那一款软件.一起来看看吧! 1.两者特点 ...

  2. 导入网页数据到 Google Sheet

    数据没有用,我们需要的是数据所反映出来的东西.增长率,排名,占比等.而这些结果是通过分析数据得到的. 从网上搜集到数据后,导入到表格程序中便可以进行方便地分析处理了.下面介绍将网页中的表格数据导入到 ...

  3. Java NIO学习笔记六 SocketChannel 和 ServerSocketChannel

    Java NIO SocketChannel Java NIO SocketChannel是连接到TCP网络socket(套接字)的通道.Java NIO相当于Java Networking的sock ...

  4. EF架构~codeFirst从初始化到数据库迁移

    一些介绍 CodeFirst是EntityFrameworks的一种开发模式,即代码优先,它以业务代码为主,通过代码来生成数据库,并且加上migration的强大数据表比对功能来生成数据库版本,让程序 ...

  5. Docker 初步认识

    1.docker 是什么? 一个开源的应用容器引擎,个人理解 就是虚拟的应用运行环境. 2.安装Docker for windows 下载地址 :https://store.docker.com/ed ...

  6. 通过java反射得到javabean的属性名称和值参考

    通过java反射得到javabean的属性名称和值 Field fields[]=cHis.getClass().getDeclaredFields();//cHis 是实体类名称 String[] ...

  7. HTML5+CSS3实现的响应式垂直时间轴

    <!DOCTYPE HTML><html><head><meta charset="utf-8"><meta name=&qu ...

  8. pouchdb-find( pouchdb查询扩展插件 ,便于查询)

    pouchdb-find pouchdb-find 环境搭建 下载lib bower install pouchdb-find 引入js <script src="pouchdb.js ...

  9. JavaScript 定义 类

    JavaScript 定义 类 一 构建类的原则 构造函数 等于 原型的constructor //构造函数 function Hero(name,skill){ this.name = name; ...

  10. 个人开源项目testall 持续更新中···

    项目在GitHub上:https://github.com/x113773/testall ,喜欢的给个星星呀,亲~ 打算把用到过的和学习过的,所有前后端技术都集成到这个项目里,并在issues里配以 ...