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;
/**
* 备忘录测试
*
* @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 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)对象状态的存储,对于用户或使用来者说,是屏蔽的,用户无需关心怎么实现,只需要启用备忘模式即可
* 缺点:
* 大量的对象的状态存储,需要耗费大量的资源,比如内存资源的消耗
*/
}
package com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚;
import java.util.List;
/**
* 原始数据类
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class OriginData {
private static int num = 0 ;
private List data;
public OriginData(List 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 getData() {
return data;
}
public void setData(List 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();
}
}
package com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚;
import java.util.ArrayList;
import java.util.List;
/**
* 事务日志类
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class TransitionJournal {
/**
* 日志序号
*/
private Integer logNum ;
/**
* 假设数据是存进数据库的
*/
private List data = new ArrayList<>();
public TransitionJournal(Integer logNum , List 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 getData() {
return data;
}
public void setData(List data) {
this.data = data;
}
}
package com.zhaoshuangjian.mode19_备忘录模式.mode19.事务回滚;
import java.util.HashMap;
import java.util.Map;
/**
* 事务存储类,每一个事务的提交日志都存储在该类中
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class TransitionStorage {
private Map logMap = new HashMap<>();
public TransitionStorage(TransitionJournal journal) {
logMap.put(journal.getLogNum(),journal);
}
/**
* 根据事务日志ID获取对应的事务日志
* @param logNum 事务日志ID
* @return 事务日志对象
*/
public TransitionJournal getLogMap(Integer logNum) {
return logMap.get(logNum);
}
public void setLogMap(Map logMap) {
this.logMap = logMap;
}
public void backup(TransitionJournal journal){
this.logMap.put(journal.getLogNum(),journal);
}
}
package com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式;
/**
* 备忘录类
*
* @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;
}
}
package com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式;
/**
* 原始类
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class Original {
/**
* 备忘录的值
*/
private String value;
public Original(String value) {
this.value = value;
}
/**
* 创建一个备忘录
* @return 备忘录对象
*/
public Memento createMemento(){
/**
* 每次都创建一个备忘录对象,并将旧值当参数给它
* 也就是新进来的值,影响不到原来的备忘录对象
*/
return new Memento(value);
}
/**
* 恢复备忘录的值
* @param memento 备忘录对象
*/
public void restoreMemento(Memento memento){
this.value = memento.getValue();
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.zhaoshuangjian.mode19_备忘录模式.mode19.传统模式;
/**
* 存储备忘录的内容,可以理解为,备忘录如果是一本书的话,那存储类就是一个抽屉或者其他
*
* @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;
}
}