备忘录模式
备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,在对象之外保存这个状态,这样就可以将对象恢复到原来的状态上。
角色:1.Originator发起人角色:记录当前时刻的内部状态,负责创建和恢复备忘录数据。
2.Memento备忘录角色:负责存储发起人的内部状态。
3.Caretaker备忘录管理员角色:对备忘录进行管理。
适用场景:需要保存数据和恢复数据的地方。有回滚的操作。数据库的事务管理。
具体实现:
通用实现
1.创建发起人角色
/**
* 发起人角色
*/
public class Originator {
//内部状态
private String state = "";
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//创建一个备忘录
public Memnto createM(){
return new Memnto(this.state);
}
//恢复一个备忘录
public void restM(Memnto memnto){
this.setState(memnto.getState());
}
}
2.创建备忘录角色
/**
* 备忘录角色
*/
public class Memnto {
private String state = "";
public Memnto(String state){
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
3.创建备忘录管理角色
/**
* 备忘录管理角色
*/
public class Caretaker {
private Memnto memnto;
public Memnto getMemnto() {
return memnto;
}
public void setMemnto(Memnto memnto) {
this.memnto = memnto;
}
}
4.创建场景测试类
/**
* 场景测试类
*/
public class Client {
public static void main(String[] args) {
//定义出发起人
Originator originator = new Originator();
originator.setState("1");
System.out.println("初始状态是:"+originator.getState());
//备份
Caretaker caretaker = new Caretaker();
caretaker.setMemnto(originator.createM());
//修改状态
originator.setState("2");
System.out.println("修改后的状态是:"+originator.getState());
//恢复状态
originator.restM(caretaker.getMemnto());
System.out.println("恢复后的状态是:"+originator.getState());
}
}
发起人融合备忘录和备忘录管理角色(利用原型模式,可以直接复制一个对象的状态)
1.修改发起人类
/**
* 发起人角色
* 实现Cloneable,才可复制
*/
public class Originator implements Cloneable{
//以前的状态
private Originator back;
//内部状态
private String state = "";
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
//创建一个备忘录
public void createM() throws CloneNotSupportedException {
this.back = this.clone();
}
//恢复一个备忘录
public void restM(){
this.setState(this.back.getState());
}
@Override
protected Originator clone() throws CloneNotSupportedException {
return (Originator) super.clone();
}
}
2.修改场景类
/**
* 场景测试类
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//定义出发起人
Originator originator = new Originator();
originator.setState("1");
System.out.println("初始状态是:"+originator.getState());
//备份
originator.createM();
//修改状态
originator.setState("2");
System.out.println("修改后的状态是:"+originator.getState());
//恢复状态
originator.restM();
System.out.println("恢复后的状态是:"+originator.getState());
}
}
多状态的备忘录模式(发起人有多个状态)
1.添加工具类
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* 工具类
*/
public class BeanUtils {
//将bean中的所有属性值放入到Map中
public static Map<String,Object> backupProp(Object bean){
Map<String,Object> result = new HashMap<>();
try {
//获取bean描述
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
//获取属性描述
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
//遍历所有属性
for(PropertyDescriptor des:propertyDescriptors){
//属性名称
String fieldName = des.getName();
//读取属性的方法
Method getter = des.getReadMethod();
//读取属性值
Object filedValue = getter.invoke(bean, new Object[]{});
if(!fieldName.equals("class")){
result.put(fieldName,filedValue);
}
}
}catch (Exception e){
}
return result;
}
//将Map中的值返回到bean中
public static void restoreProp(Object bean,Map<String,Object> propMap){
try{
//获取bean描述
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
//获取属性描述
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
//遍历所有属性
for(PropertyDescriptor des:propertyDescriptors) {
//属性名称
String fieldName = des.getName();
if (propMap.containsKey(fieldName)) {
//写属性的方法
Method setter = des.getWriteMethod();
setter.invoke(bean,new Object[]{propMap.get(fieldName)});
}
}
}catch (Exception e){
}
}
}
2.修改发起人类
/**
* 发起人角色
*/
public class Originator {
//内部状态
private String state1 = "";
private String state2 = "";
private String state3 = "";
//创建一个备忘录
public Memnto createM() throws CloneNotSupportedException {
return new Memnto(BeanUtils.backupProp(this));
}
//恢复一个备忘录
public void restM(Memnto memnto){
BeanUtils.restoreProp(this,memnto.getStateMap());
}
public String getState1() {
return state1;
}
public void setState1(String state1) {
this.state1 = state1;
}
public String getState2() {
return state2;
}
public void setState2(String state2) {
this.state2 = state2;
}
public String getState3() {
return state3;
}
public void setState3(String state3) {
this.state3 = state3;
}
@Override
public String toString() {
return "Originator{" +
"state1='" + state1 + '\'' +
", state2='" + state2 + '\'' +
", state3='" + state3 + '\'' +
'}';
}
}
3.修改场景类
/**
* 场景测试类
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//定义出发起人
Originator originator = new Originator();
originator.setState1("1");
originator.setState2("11");
originator.setState3("111");
System.out.println("初始状态是:"+originator);
//备份
Memnto m = originator.createM();
//修改状态
originator.setState1("2");
originator.setState2("22");
originator.setState3("222");
System.out.println("修改后的状态是:"+originator);
//恢复状态
originator.restM(m);
System.out.println("恢复后的状态是:"+originator);
}
}
多备份模式(多级备份)
1.修改备忘录管理者角色
**
* 备忘录管理角色
*
*/
public class Caretaker {
//用一个Map存放多级备忘录
private Map<String,Memnto> memMap = new HashMap<>();
public Memnto getMemMap(String idx) {
return memMap.get(idx);
}
public void setMemMap(String idx,Memnto memnto) {
this.memMap.put(idx,memnto);
}
}
2.修改场景类
/**
* 场景测试类
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//定义出发起人
Originator originator = new Originator();
//定义出备忘录管理人员
Caretaker caretaker = new Caretaker();
originator.setState1("1");
originator.setState2("11");
originator.setState3("111");
System.out.println("初始状态是:"+originator);
//备份
caretaker.setMemMap("001",originator.createM());
//修改状态
originator.setState1("2");
originator.setState2("22");
originator.setState3("222");
System.out.println("修改后的状态是:"+originator);
//备份
caretaker.setMemMap("002",originator.createM());
//恢复状态
originator.restM(caretaker.getMemMap("001"));
System.out.println("恢复后的状态是:"+originator);
}
}
更好的安全性和封装性(将Memnto类放入Originator中,实现IMemnto接口。外部只能访问接口,而不知道Memnto类的内部)
1.创建备忘录空接口
/**
* 备忘录的空接口
*/
public interface IMemento {
}
2.修改发起人类
/**
* 发起人角色
*/
public class Originator {
//内部状态
private String state1 = "";
private String state2 = "";
private String state3 = "";
//创建一个备忘录
public Memnto createM() throws CloneNotSupportedException {
return new Memnto(BeanUtils.backupProp(this));
}
//恢复一个备忘录
public void restM(Memnto memnto){
BeanUtils.restoreProp(this,memnto.getStateMap());
}
public String getState1() {
return state1;
}
public void setState1(String state1) {
this.state1 = state1;
}
public String getState2() {
return state2;
}
public void setState2(String state2) {
this.state2 = state2;
}
public String getState3() {
return state3;
}
public void setState3(String state3) {
this.state3 = state3;
}
@Override
public String toString() {
return "Originator{" +
"state1='" + state1 + '\'' +
", state2='" + state2 + '\'' +
", state3='" + state3 + '\'' +
'}';
}
//内置类
private class Memnto implements IMemento{
//以一个Map存放状态
private Map<String,Object> stateMap;
public Memnto(Map<String,Object> stateMap){
this.stateMap = stateMap;
}
public Map<String, Object> getStateMap() {
return stateMap;
}
public void setStateMap(Map<String, Object> stateMap) {
this.stateMap = stateMap;
}
}
}
3.修改备忘录管理者类
/**
* 备忘录管理角色
*
*/
public class Caretaker {
//用一个Map存放多级备忘录
private Map<String,IMemento> memMap = new HashMap<>();
public IMemento getMemMap(String idx) {
return memMap.get(idx);
}
public void setMemMap(String idx,IMemento memnto) {
this.memMap.put(idx,memnto);
}
}