研磨设计模式学习笔记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中设计模式之一,但在软件开发中应用也较为 ...
随机推荐
- Luogu 3942 将军令
之前写那个(Luogu 2279) [HNOI2003]消防局的设立的时候暴力推了一个树形dp,然后就导致这个题不太会写. 贪心,先把树建出来,然后考虑按照结点深度排个序,每次取出还没有被覆盖掉的深度 ...
- Netty服务端的业务流程分析
Netty的服务端怎么和java NIO联系起来的,一直很好奇这块内容,这里跟下代码,下篇文章看下Channel相关的知识. finalChannelFuture initAndRegister(){ ...
- ZOJ 2301 Color the Ball (离散化+线段树)
题意:有从 1 开始递增依次编号的很多球,开始他们都是黑色的,现在依次给出 n 个操作(ai,bi,ci),每个操作都是把编号 ai 到 bi 区间内 的-所有球涂成 ci 表示的颜色(黑 or 白) ...
- Git相关安装包打包下载
Git相关软件偶尔需要***才能下载,故分享于此 1.Git-2.15.0-64-bit.exe 2.TortoiseGit-2.5.0.0-64bit.msi 3.TortoiseGit-Langu ...
- c++ 类成员变量初始化总结
最近在学习c++,不同类型的c++成员变量在初始化的时候也有很有的区别,查了一些资料之后再此记录一下: #include<iostream> using namespace std; // ...
- iOS组件化方案
一.蘑菇街url-block方案 这是蘑菇街中应用的一种页面间调用的方式,通过在启动时注册组件提供的服务,把调用组件使用的url和组件提供的服务block对应起来,保存到内存中.在使用组件的服务时,通 ...
- Java 表达式解析(非原创)
因项目需要,在网上找来一套表达式解析方法,由于原来的方法太过于零散,不利于移植,现在整理在同一文件内: 文件中包含5个内部类,源码如下: import java.util.ArrayList; imp ...
- docker初探
1.什么是docker: 可以理解为一个可移植的集装箱容器,开发者可以打包他们的应用以及依赖包到一个可移植的容器中. 2.docker安装及使用(ubuntu16.04) (1)首先通过apt-get ...
- VB-机房收费系统之Excel导出
敲机房很久了,感觉对代码的感知力终于有所提高了,很是开心.今天在敲学生充值记录查询的时候发现,其中有了新的知识, 这时候就该到了分析问题的时候了.不说废话了! 首先 保证自己的笔记本或者电脑上必须有 ...
- Python 模拟简单区块链
首先这是说明一下这是Tiny熊老师的教程https://www.cnblogs.com/tinyxiong 另外还要说明一下,暑假指导老师让我们做一些关于区块链的应用.这里只是涉及极其简单的模拟,主要 ...