1.备忘录测试
package com.zhaoshuangjian.mode19_备忘录模式; import com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚.OriginData; import com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚.TransitionStorage; import com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式.Original; import com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式.Storage; import java.util.ArrayList; import java.util.List; /** * <p>备忘录测试</p> * * @Author zhaoshuangjian 2023-03-25 下午21:44 */ public class MementoTest { public static void main(String[] args) { // 1、传统备忘录模式 memento(); System.out.println("========================== ========================="); // 2、模拟事务回滚 transition(); } private static void memento(){ Original original = new Original("明天周一,我们去吃火锅吧!"); // 1、为了记住明天事情,我需要将这条信息记录下来 Storage storage = new Storage(original.createMemento()); System.out.println("主意没变前:"+original.getValue()); // 2、明天,我又想吃北京烤鸭了 original.setValue("明天周一,我们还是去吃北京烤鸭吧!"); System.out.println("主意改变后:"+original.getValue()); /** * 3、后来想了想,我还是不吃北京烤鸭了,这个太油腻了 * 但是我又想不起来之前我想要吃什么了,怎么办,我们去翻一下备忘录好了 * 我们从抽屉里拿出我们的备忘录,然后恢复下 */ original.restoreMemento(storage.getMemento()); // 4、通过翻看之前记录在备忘录里面的内容,我发现明天我是要吃火锅的 System.out.println("主意反悔后:"+original.getValue()); } private static void transition(){ // 初始化三条数据 List<Integer> data = new ArrayList<>(); data.add(1); data.add(2); data.add(3); OriginData originData = new OriginData(data); // 1、添加一个元素,添加前,先备份下 TransitionStorage storage = new TransitionStorage(originData.createJournal()); printLog("增加一个数据前",originData); originData.addData(4); // 2、添加一个元素后,再备份下 storage.backup(originData.createJournal()); printLog("增加一个数据后",originData); // 3、删除一个元素前 originData.remove(2); // 4、删除一个元素后,备份下 storage.backup(originData.createJournal()); printLog("删除一个数据后",originData); /** * 5、现在有了两次操作,一次增加,一次删除,现在我们要恢复到删除前的数据 * 即回滚事务日志ID = 2的记录 */ originData.restoreJournal(storage.getLogMap(2)); printLog("根据事物日志id=2,恢复数据后",originData); } private static void printLog(String message,OriginData originData){ System.out.println(message+originData+",当前事务日志ID:"+originData.getLogNum()); } /** * 百科如此描述备忘录模式: * 在不破坏封闭的前提下,捕获一个对象的内部状态, * 并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态 * * 这个不难理解,其实就是把我们之前写下来的东西记录起来,然后放在一个专门存储的地方存起来 * * 优点: * (1)对象的状态可以被存储和管理起来,对象的状态可以任意回退,不用担心由于误操作而造成对象状态的丢失 * (2)对象状态的存储,对于用户或使用来者说,是屏蔽的,用户无需关心怎么实现,只需要启用备忘模式即可 * 缺点: * 大量的对象的状态存储,需要耗费大量的资源,比如内存资源的消耗 */ }
2.原始数据类
package com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚; import java.util.List; /** * <p>原始数据类</p> * * @Author zhaoshuangjian 2023-03-25 下午21:44 */ public class OriginData { private static int num = 0 ; private List<Integer> data; public OriginData(List<Integer> data) { this.data = data; } public TransitionJournal createJournal(){ return new TransitionJournal(++num , data); } public void restoreJournal(TransitionJournal journal){ this.data = journal.getData(); num = journal.getLogNum(); } public List<Integer> getData() { return data; } public void setData(List<Integer> data) { this.data = data; } public void addData(Integer val){ this.data.add(val); } public void remove(Integer val){ this.data.remove(val); } public int getLogNum(){ return num; } @Override public String toString(){ return this.data.toString(); } }
3.事务日志类
package com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚; import java.util.ArrayList; import java.util.List; /** * <p>事务日志类</p> * * @Author zhaoshuangjian 2023-03-25 下午21:44 */ public class TransitionJournal { /** * 日志序号 */ private Integer logNum ; /** * 假设数据是存进数据库的 */ private List<Integer> data = new ArrayList<>(); public TransitionJournal(Integer logNum , List<Integer> data) { this.logNum = logNum; if(data != null && data.size() > 0){ this.data.addAll(data); } } public Integer getLogNum() { return logNum; } public void setLogNum(Integer logNum) { this.logNum = logNum; } public List<Integer> getData() { return data; } public void setData(List<Integer> data) { this.data = data; } }
4.事务存储类,每一个事务的提交日志都存储在该类中
package com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚; import java.util.HashMap; import java.util.Map; /** * <p>事务存储类,每一个事务的提交日志都存储在该类中</p> * * @Author zhaoshuangjian 2023-03-25 下午21:44 */ public class TransitionStorage { private Map<Integer , TransitionJournal> logMap = new HashMap<>(); public TransitionStorage(TransitionJournal journal) { logMap.put(journal.getLogNum(),journal); } /** * <p>根据事务日志ID获取对应的事务日志</p> * @param logNum 事务日志ID * @return 事务日志对象 */ public TransitionJournal getLogMap(Integer logNum) { return logMap.get(logNum); } public void setLogMap(Map<Integer, TransitionJournal> logMap) { this.logMap = logMap; } public void backup(TransitionJournal journal){ this.logMap.put(journal.getLogNum(),journal); } }
5.备忘录类
package com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式; /** * <p>备忘录类</p> * * @Author zhaoshuangjian 2023-03-25 下午21:44 */ public class Memento { /** * 真正备忘录里面的值 */ private String value ; public Memento(String value){ this.value = value ; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
6.原始类
package com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式; /** * <p>原始类</p> * * @Author zhaoshuangjian 2023-03-25 下午21:44 */ public class Original { /** * 备忘录的值 */ private String value; public Original(String value) { this.value = value; } /** * <p>创建一个备忘录</p> * @return 备忘录对象 */ public Memento createMemento(){ /** * 每次都创建一个备忘录对象,并将旧值当参数给它 * 也就是新进来的值,影响不到原来的备忘录对象 */ return new Memento(value); } /** * <p>恢复备忘录的值</p> * @param memento 备忘录对象 */ public void restoreMemento(Memento memento){ this.value = memento.getValue(); } public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
7.存储备忘录的内容,可以理解为,备忘录如果是一本书的话,那存储类就是一个抽屉或者其他
package com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式; /** * <p>存储备忘录的内容,可以理解为,备忘录如果是一本书的话,那存储类就是一个抽屉或者其他</p> * * @Author zhaoshuangjian 2023-03-25 下午21:44 */ public class Storage { /** * 关联一个备忘录对象,这种模式真的是很常见啊 * 注意,这里可以是一个列表,也可以是单个对象 * 是单数还是复数,具体看storage的业务需要 */ private Memento memento ; public Storage(Memento memento) { this.memento = memento; } public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } }