研磨设计模式学习笔记3--适配器模式Adapter
需求:制作一个日志管理系统,分为2个版本,第一版制作一个将日志存在本地文件的管理系统,第二版制作一个存储在数据库的管理系统,同时,第二版兼容第一版。
优点:可以复用现有功能,无需重新开发。
一、第一版日志系统存储本地
日志domain类
@Data
@Builder
public class LogModel implements Serializable{
private String logId;
private String operUser;
private String operTime; @Override
public String toString() {
return "LogModel{" +
"logId='" + logId + '\'' +
", operUser='" + operUser + '\'' +
", operTime='" + operTime + '\'' +
", content='" + content + '\'' +
'}';
}
private String content;
}
日志管理接口
public interface LogFileOperateApi {
void writeLogFile(List<LogModel> list);
List<LogModel> readLogFile();
}
日志管理实现类
public class LogFileOperateImpl implements LogFileOperateApi {
private String logFilePathName = "";
LogFileOperateImpl(String logFilePathName){
File file = new File(logFilePathName);
if(!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
this.logFilePathName = logFilePathName;
}
@Override
public void writeLogFile(List<LogModel> list) {
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File(logFilePathName)));
objectOutputStream.writeObject(list);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public List<LogModel> readLogFile() {
List<LogModel> list = null;
ObjectInputStream objectInputStream = null;
try {
objectInputStream = new ObjectInputStream(new FileInputStream(new File(logFilePathName)));
} catch (Exception e) {
e.printStackTrace();
}
try {
list = (List<LogModel>) objectInputStream.readObject() ;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return list;
}
}
客户端
public class Client {
public static void main(String[] args) {
LogFileOperateApi logFileOperateImpl = new LogFileOperateImpl("d:/1.log");
List<LogModel> list = new LinkedList<>();
list.add(LogModel.builder().logId("1").operTime("2900-10-14").operUser("lby").content("hallo").build());
list.add(LogModel.builder().logId("2").operTime("2900-10-15").operUser("lby").content("hello").build());
logFileOperateImpl.writeLogFile(list);
List<LogModel> logModels = logFileOperateImpl.readLogFile();
System.out.println(logModels);
}
}
到此,第一版日志系统已经完成。
二、第二版日志系统存储数据库
日志管理接口
public interface LogDbOperateApi {
void createLog(List<LogModel> list);
void removeLog(LogModel logModel);
void updateLog(LogModel logModel);
List<LogModel> getAllLogs();
}
日志管理实现类(简化了实现过程)
public class LogDbOperateImpl implements LogDbOperateApi{
@Override
public void createLog(List<LogModel> list) {
System.out.println("DB createLog"+list);
}
@Override
public void removeLog(LogModel logModel) {
System.out.println("DB removeLog"+logModel);
}
@Override
public void updateLog(LogModel logModel) {
System.out.println("DB updateLog"+logModel);
}
@Override
public List<LogModel> getAllLogs() {
System.out.println("DB getAllLogs");
return null;
}
}
客户端测试
public class Client {
public static void main(String[] args) {
LogDbOperateApi logDbOperateApi = new LogDbOperateImpl();
List <LogModel> list = new ArrayList<>();
list.add(LogModel.builder().content("test").build());
logDbOperateApi.createLog(list);
logDbOperateApi.removeLog(LogModel.builder().content("test").build());
logDbOperateApi.updateLog(LogModel.builder().content("test").build());
logDbOperateApi.getAllLogs();
}
}
三、第二版日志管理系统也开发好了,这个时候客户需要第二版的管理系统兼容第一版。
改造:无需重新开发支持第一版,引入adapter利用现有的LogFileOperateApi接口,转化为LogDbOperateApi接口。
public class Adapter implements LogDbOperateApi {
LogFileOperateApi logFileOperateApi;
Adapter(LogFileOperateApi logFileOperateApi){
this.logFileOperateApi = logFileOperateApi;
}
@Override
public void createLog(List<LogModel> list) {
logFileOperateApi.writeLogFile(list);
}
@Override
public void removeLog(LogModel logModel) {
List<LogModel> list = logFileOperateApi.readLogFile();
list.forEach(item->{
logModel.getLogId().equals(item.getLogId());
list.remove(item);
});
logFileOperateApi.writeLogFile(list);
}
@Override
public void updateLog(LogModel logModel) {
List<LogModel> list = logFileOperateApi.readLogFile();
list.forEach(item->{
logModel.getLogId().equals(item.getLogId());
list.remove(item);
});
list.add(logModel);
logFileOperateApi.writeLogFile(list);
}
@Override
public List<LogModel> getAllLogs() {
return logFileOperateApi.readLogFile();
}
}
客户端测试
public class Client {
public static void main(String[] args) {
LogFileOperateApi logFileOperateImpl = new LogFileOperateImpl("d:/1.log");
LogDbOperateApi logDbOperateApi = new Adapter(logFileOperateImpl);
System.out.println(logDbOperateApi.getAllLogs());
logDbOperateApi.updateLog(LogModel.builder().logId("1").operTime("6666-10-14").operUser("lby").content("hallo").build());
System.out.println(logDbOperateApi.getAllLogs());
}
}
四、双向兼容
已经完成了第二版日志管理系统兼容第一版,继续改造,利用双向适配器将系统改造成,两个版本相互兼容。
public class TwoDeriectApater implements LogDbOperateApi,LogFileOperateApi {
private LogDbOperateApi logDbOperateApi;
private LogFileOperateApi logFileOperateApi;
public TwoDeriectApater(LogDbOperateApi logDbOperateApi,LogFileOperateApi logFileOperateApi){
this.logDbOperateApi = logDbOperateApi;
this.logFileOperateApi = logFileOperateApi;
}
/**
*
* --------------以下为第二版兼容第一版部分----------
*/
@Override
public void createLog(List<LogModel> list) {
logFileOperateApi.writeLogFile(list);
}
@Override
public void removeLog(LogModel logModel) {
List<LogModel> list = logFileOperateApi.readLogFile();
list.forEach(item->{
logModel.getLogId().equals(item.getLogId());
list.remove(item);
});
logFileOperateApi.writeLogFile(list);
}
@Override
public void updateLog(LogModel logModel) {
List<LogModel> list = logFileOperateApi.readLogFile();
list.forEach(item->{
logModel.getLogId().equals(item.getLogId());
list.remove(item);
});
list.add(logModel);
logFileOperateApi.writeLogFile(list);
}
@Override
public List<LogModel> getAllLogs() {
return logFileOperateApi.readLogFile();
}
/**
*
* --------------以下为第一版兼容第二版部分----------
*/
@Override
public void writeLogFile(List<LogModel> list) {
logDbOperateApi.createLog(list);
}
@Override
public List<LogModel> readLogFile() {
return logDbOperateApi.getAllLogs();
}
}
客户端测试
public class Client {
public static void main(String[] args) {
LogFileOperateApi logFileOperateImpl = new LogFileOperateImpl("d:/1.log");
LogDbOperateApi logDbOperateImpl = new LogDbOperateImpl();
LogFileOperateApi fileApi = new TwoDeriectApater(logDbOperateImpl,logFileOperateImpl);
LogDbOperateApi dbApi = new TwoDeriectApater(logDbOperateImpl,logFileOperateImpl);
List<LogModel> list = new LinkedList<>();
list.add(LogModel.builder().logId("1").operTime("8888-10-14").operUser("lby").content("hallo").build());
list.add(LogModel.builder().logId("2").operTime("2222-10-15").operUser("lby").content("hello").build());
dbApi.createLog(list);
System.out.println(dbApi.getAllLogs());
System.out.println(fileApi.readLogFile());
}
}
研磨设计模式学习笔记3--适配器模式Adapter的更多相关文章
- 研磨设计模式学习笔记4--单例模式Signleton
需求:加载配置文件,由于配置文件全局唯一,所以不用过多对象,建一个就可以了. 优点:单例模式本质就是为了控制实例数目. 一.饿汉式 public class Singleton { private S ...
- 研磨设计模式学习笔记2--外观模式Facade
需求:客户端需要按照需求,执行一个操作,操作包括一个系统中的3个模块(根据配置选择是否全部执行). 外观模式优点: 客户端无需知道系统内部实现,,只需要写好配置文件,控制那些模块执行,简单易用. 外观 ...
- 研磨设计模式学习笔记1--简单工厂(SimpleFactory)
需求:实现一个简单工厂,客户端根据需求获取实现类. 简单工厂优点: 客户端不需要知道工厂内部实现,然组件外部实现面向接口编程. 客户端.实现类解耦. 一.接口及实现类 //接口 public inte ...
- 7 种 Javascript 常用设计模式学习笔记
7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...
- 设计模式(五)适配器模式Adapter(结构型)
设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...
- C#设计模式学习笔记-单例模式随笔
最近学习 设计模式,从单例模式入手 啥是单例模式: 要实现一个单例类的话,首先,肯定是不能让用户自行生产的,那就是说明不能让用户new,所以,就必须把构造函数设置成为私有的 因为静态变量的生命周期跟整 ...
- 设计模式学习笔记--备忘录(Mamento)模式
写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方式,这就是软件模式:每个模式描写叙述了一个在我们程序设计中常常发生的问题,以及该问题的解决方式:当我们碰到模 ...
- C#设计模式学习笔记-单例模式(转)
C#设计模式学习笔记-单例模式 http://www.cnblogs.com/xun126/archive/2011/03/09/1970807.html 最近在学设计模式,学到创建型模式的时候,碰到 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
随机推荐
- HDOJ 1196 Lowest Bit
题目大意是给一个1-100的整数,要求首先转化成2进制,然后从最低位开始数起到不是0的位停止,输出这些位代表队额10进制数 #include <iostream> using namesp ...
- Android调试之Logcat
转贴 http://www.cnblogs.com/adison/p/4264284.html 在Android开发过程中,总免不了要调试,无论是Debug,还是Android自带的Logcat,抑 ...
- STL之priority_queue(优先队列)
priority_queue是一个容器适配器,在这个容器里第一个数据元素是最大的.它的使用场景是什么样:如果12306抢票,为什么黄牛能抢这么多票,感觉12306那边的请求队列是一个优先队列,黄牛的请 ...
- 【Java学习】Java迭代器
迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的.只要拿到这个对象,使用迭代器就可以遍历这个对象的内部. 1.Iterator ...
- arcgis调用国家天地图wfs服务
1.国家天地图wfs地址 getcapabilities http://www.tianditu.com/wfssearch.shtml?request=getcapabilities&ser ...
- 事件Event 介绍总结
最近在总结一些基础的东西,主要是学起来很难懂,但是在日常又有可能会经常用到的东西.前面介绍了 C# 的 AutoResetEvent的使用介绍, 这次介绍事件(event). 事件(event),对于 ...
- baidumap应用
需要在安卓平台利用baidumap SDK进行二次开发, 注册好,创建应用 利用jdk/bin里的keytool做Android SDK安全码 进入.android(参照下图):输入keytool - ...
- Oracle中With As 、Group By 语法
比如有下面三张表,用With as .Group By语法解决几个问题; with as : 可以用来创建临时表,作为过度的表: group by: 按照某个字段来分类: 对应字段如下: Sa ...
- linux进程切换问题
#define switch_to(prev,next,last) do { \ unsigned long esi,edi; \ asm volatile("pushfl\n\t" ...
- 数据结构8: 双向链表(双向循环链表)的建立及C语言实现
之前接触到的链表都只有一个指针,指向直接后继,整个链表只能单方向从表头访问到表尾,这种结构的链表统称为 “单向链表”或“单链表”. 如果算法中需要频繁地找某结点的前趋结点,单链表的解决方式是遍历整个链 ...