需求:制作一个日志管理系统,分为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的更多相关文章

  1. 研磨设计模式学习笔记4--单例模式Signleton

    需求:加载配置文件,由于配置文件全局唯一,所以不用过多对象,建一个就可以了. 优点:单例模式本质就是为了控制实例数目. 一.饿汉式 public class Singleton { private S ...

  2. 研磨设计模式学习笔记2--外观模式Facade

    需求:客户端需要按照需求,执行一个操作,操作包括一个系统中的3个模块(根据配置选择是否全部执行). 外观模式优点: 客户端无需知道系统内部实现,,只需要写好配置文件,控制那些模块执行,简单易用. 外观 ...

  3. 研磨设计模式学习笔记1--简单工厂(SimpleFactory)

    需求:实现一个简单工厂,客户端根据需求获取实现类. 简单工厂优点: 客户端不需要知道工厂内部实现,然组件外部实现面向接口编程. 客户端.实现类解耦. 一.接口及实现类 //接口 public inte ...

  4. 7 种 Javascript 常用设计模式学习笔记

    7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...

  5. 设计模式(五)适配器模式Adapter(结构型)

      设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...

  6. C#设计模式学习笔记-单例模式随笔

    最近学习 设计模式,从单例模式入手 啥是单例模式: 要实现一个单例类的话,首先,肯定是不能让用户自行生产的,那就是说明不能让用户new,所以,就必须把构造函数设置成为私有的 因为静态变量的生命周期跟整 ...

  7. 设计模式学习笔记--备忘录(Mamento)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方式,这就是软件模式:每个模式描写叙述了一个在我们程序设计中常常发生的问题,以及该问题的解决方式:当我们碰到模 ...

  8. C#设计模式学习笔记-单例模式(转)

    C#设计模式学习笔记-单例模式 http://www.cnblogs.com/xun126/archive/2011/03/09/1970807.html 最近在学设计模式,学到创建型模式的时候,碰到 ...

  9. Java设计模式学习笔记(二) 简单工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...

随机推荐

  1. Java Learning 002 Eclipse软件 打开一个工程 和 运行这个工程

    Java Eclipse软件 打开一个工程 和 运行这个工程 我在网上下载了一个 Java 工程源代码.使用Eclipse软件打开这个工程,打开方式有些特别: Step 1 . 点击: File -& ...

  2. p2234&bzoj1588 营业额统计

    传送门 题目 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额 ...

  3. 数据结构--树--AVL树

    详情查看:http://www.cnblogs.com/skywang12345/p/3577360.html

  4. Ubuntu中安装LAMP

    现在,很多人可能已经用上ubuntu了,大家可能花了大量时间在ubuntu的美化上,这无可厚非,但是,ubuntu应该给我们的工作和学习带来更多的便利和方便.ubuntu作为linux,为我们提供了强 ...

  5. Spring Bean的装配

    Bean 的装配,即Bean对象的创建.容器根据代码要求创建Bean对象后再传递给代码的过程,称为Bean的装配. 一.默认分的装配方式 默认的装配的方式调用Bean类的构造方法 二.动态工厂Bean ...

  6. c# interface(接口)和abstract(抽象类)区别

    抽象类依然是一个类,不能被实例化,可以包含字段.成员变量.抽象方法.或者不抽象方法. 类继承抽象类,只重写抽象方法即可,其他是可以得到继承的. 接口是规则,里面只包含:方法.属性.索引.事件.类继承接 ...

  7. 利用excel制作二维码

    1 将想要通过扫描二维码访问的目标网址放入A1单位格 2 在excel 编辑区右击选择“自定义功能区” 3 然后将“开发者工具”选上 4 点击菜单栏的“开发者工具---插入--->其他控件” 5 ...

  8. 常用SQL语句及在node中使用MySQL

    摘要:一些重要的SQL命令 SELECT - 从数据库中提取数据 UPDATE - 更新数据库中的数据 DELETE - 从数据库中删除数据 INSERT INTO - 向数据库中插入新数据 CREA ...

  9. Codeforces Round #541 (Div. 2)D(并查集(dsu),拓扑排序)

    #include<bits/stdc++.h>using namespace std;vector<int>g[2007];int fa[2007],vis[2007],num ...

  10. C语言数据结构-顺序线性表的实现-初始化、销毁、长度、查找、前驱、后继、插入、删除、显示操作

    1.数据结构-顺序线性表的实现-C语言 #define MAXSIZE 100 //结构体定义 typedef struct { int *elem; //基地址 int length; //结构体当 ...