已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
设计模式之-适配器适配器模式先考虑这种设计模式适用场景:假如我们有一个运行良好的接口以及其实现,(Version 1.0,比如说是按照用户要求开发的日志系统,这个日志系统是基于文件记录的FileLogger),但是由于系统升级或者用户需求变化等,我们又设计了一个新的接口以及实现(Version 2.0,比如说是按照用户的要求,让日志系统是基于数据库记录的DBLogger),并且这个新设计的接口也能良好运行.假如到此为止,我们还没看出设计模式的用武之地。然而,我们知道,用户的需求创意是无穷无尽的,现在用户说了,我们想同时用这两种日志系统.就是说,现如今的业务是运行在Version 2.0 的接口上,但是我要用 Version 1.0的实现.好,需求出来了,那么怎么实现呢?两个接口的方法都不一致(兼容)?说起来也简单,大约有这么2套方案:1,我们按照DBLogger的接口,在重新开发一套,适用于文件系统的日志。2,直接修改Version 1.0 的代码。先说第一种方案,这么做确实可以,而且很直观。但是在我们已完成相应功能的前提下,再重新写一套代码其实是没有必要的,并且代码复用性也不高。从这个角度考虑,如果有更好的办法,我们可以将这个方案pass掉。再说第二种方案,第二种方案也可以解决问题,但是它暴露的问题更加明显。如果直接修改第一版本的代码,那么很可能造成其他依赖这些代码的代码不能运行,也就是存在依赖关系的约束。这个方案还不如第一个方案,所以我们毫不犹豫的把它pass!两种方案都被否定了,下面就是 适配器模式 上场了。适配器模式作用:将一个接口转化为客户端希望的另一个接口,使得原本由于接口不相容的两个类,可以相互配合的一起工作。主要就是起一个转换器的作用,目的就是复用原来的功能,说白了就是让两个接口匹配起来。想想看,适配器的作用在生活中很常见,比如管道转接头,三相插座插口转换器等。这就是 适配器模式 出现的背景.下面我们看一下代码的实现:首先看一下日志模型类(JavaBean):package mode.adaptor;/* * 这是日志对象的模型 简化点写,只有操作人和操作 * * author root * */public class LogModel private String uuid;private String operator;/ 操作人private String operate;/ 操作private String timestamp;/ 操作时间public String getUuid() return uuid;public void setUuid(String uuid) this.uuid = uuid;public String getOperator() return operator;public void setOperator(String operator) this.operator = operator;public String getOperate() return operate;public void setOperate(String operate) this.operate = operate;public String getTimestamp() return timestamp;public void setTimestamp(String timestamp) this.timestamp = timestamp;public String toString() return 用户 + this.getOperator() + 在 + this.getTimestamp()+ 做了 + this.getOperate() + 操作;然后在看一下 Version 1.0的日志系统接口,面向文件的:package mode.adaptor;import java.util.List;/* * 文件日志系统的操作接口 * author root * */public interface FileLogger public List readLog();public void writeLog(LogModel model);以及具体实现:package mode.adaptor;import java.util.List;/* * 文件日志操作的简单实现 * author root * */public class FileLoggerImpl implements FileLoggerOverridepublic List readLog() System.out.println(读取日志文件内容.);return null;Overridepublic void writeLog(LogModel model) System.out.println(写入日志文件:+model);假设这就是我们使用的Version1.0的代码,但是由于系统升级或者用户需求变化,倒是接口改变。如再下面就是 Version 2.0 的日志系统接口,是面向数据库的:package mode.adaptor;import java.util.List;/* * 数据库文件系统的操作接口 * author root * */public interface DBLogger public void addLog(LogModel model);public void updateLog(LogModel model);public void deleteLog(LogModel model);public List queryLog();以及具体实现:package mode.adaptor;import java.util.List;public class DBLoggerImpl implements DBLogger Overridepublic void addLog(LogModel model) System.out.println(写入日志数据库: + model);Overridepublic void updateLog(LogModel model) System.out.println(更新日志数据库: + model);Overridepublic void deleteLog(LogModel model) System.out.println(删除数据库日志: + model);Overridepublic List queryLog() System.out.println(查询数据库日志.);return null;最后假设是业务使用这两种日志的测试方法:public class Client private FileLogger fileLogger = null;private LogModel model = null;private DBLogger dbLogger = null;Beforepublic void init() fileLogger = new FileLoggerImpl();dbLogger = new DBLoggerImpl();model = new LogModel();model.setUuid(uuid);model.setOperate(update);model.setOperator(zhangsan);model.setTimestamp(2013-01-06 22:44:45);/* * 这是使用 Version 1.0 的业务代码 */Testpublic void useLog_v1() fileLogger.readLog();fileLogger.writeLog(model);/* *这是使用Version 2.0 的业务代码 */Testpublic void userLog_v2() dbLogger.addLog(model);dbLogger.updateLog(model);dbLogger.deleteLog(model);dbLogger.queryLog();目前为止,如果客户没有提出更加变态的需求,那么代码是可以良好运行的。但是假如说,用户又提出了一个新的需求,说我们想混合使用两种日志系统.就得在Version2.0 接口的基础上,有一个Version1.0的实现.那么,怎么办呢,这就是适配器模式的用武之地:做接口转换!package mode.adaptor;import java.util.List;/* * 这个就是传说中的转换器类.起一个转换接口的作用 * author root * */public class Adaptor implements DBLoggerprivate FileLogger filelogger = null;public Adaptor(FileLogger filelogger)this.filelogger = filelogger;Overridepublic void addLog(LogModel model) filelogger.writeLog(model);Overridepublic void updateLog(LogModel model) List list = filelogger.readLog();if(list = null)filelogger.writeLog(model);/文件日志更新:先读出来,然后在对象更新后重新写入,这里只是模拟elsefor(int i = 0; i list.size();i+)if(model.getUuid().equals(list.get(i).getUuid()list.set(i, model);for(LogModel models : list)filelogger.writeLog(models);System.out.println(更新操作完成);Overridepublic void deleteLog(LogModel model) List list = filelogger.readLog();if(list != null)if(list.contains(model)list.remove(model);for(LogModel models : list)filelogger.writeLog(models);System.out.println(删除操作完成);Overridepublic List queryLog() return filelogger.readLog();我们可以看出,适配器类必须实现 新版本(Version2.0)的接口,由于需要Version1.0的实现,所以在构造方法中需要一个Version1.0 的实现。然后想办法进行接口的转换。有了适配器类,我们就可以在客户端混合使用两种日志系统了:package mode.adaptor;import org.junit.Before;import org.junit.Test;public class Client private FileLogger fileLogger = null;private LogModel model = null;private DBLogger dbLogger = null;Beforepublic void init() fileLogger = new FileLoggerImpl();dbLogger = new DBLoggerImpl();model = new LogModel();model.setUuid(uuid);model.setOperate(update);model.setOperator(zhangsan);model.setTimestamp(2013-01-06 22
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年一级造价师之建设工程技术与计量(水利)能力测试试卷B卷附答案
- 2026届福建省全国名校联盟高三上学期期中考试历史试题(含答案)
- 职业性慢性轻度镉中毒的护理
- 2025山东滨州博兴县招聘播音主持人员2人模拟试卷附答案解析
- 2026国家移民管理局直属事业单位招聘事业编制16人笔试模拟试卷带答案解析
- 2026年消防条令纲要知识考试题库完整答案
- 2026年陕西省选调生招录(面向北京航空航天大学)历年真题汇编带答案解析
- 2025年河北石家庄晋州市中医院公开招聘工作人员21名历年真题汇编带答案解析
- 2026年金华义乌市教育系统赴清华大学、华东师范大学、杭州师范大学招聘145人历年真题汇编附答案解析
- 2026年质量员之土建质量基础知识考试题库含完整答案(各地真题)
- 学堂在线 唐宋词鉴赏 期末考试答案
- GB/T 6068-2021汽车起重机和轮胎起重机试验规范
- GB/T 13477.8-2017建筑密封材料试验方法第8部分:拉伸粘结性的测定
- 影像三基试题及答案
- BB/T 0071-2017包装玻璃容器卡式瓶口尺寸
- 农村宅基地永久转让合同
- 超高层建筑的火灾特点
- DB44∕T 1455-2014 气凝胶绝热材料
- 统编版二年级语文上册课文2 写话 :自己喜欢的玩具课件(27页)
- 教育部十二五规划子课题申报
- Q∕GDW 10827-2020 三相智能电能表技术规范
评论
0/150
提交评论