备忘录模式
2012-07-03 12:45
106 查看
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;
/**
* 设计模式之备忘录模式
*备忘录模式的优点有:
*当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。
*备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。
*
*备忘录模式的缺点:
*在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。
*
*适用场景
*如果有需要提供回滚操作的需求,使用备忘录模式非常适合,比如jdbc的事务操作,文本编辑器的Ctrl+Z恢复等。
*/
class Originator {
private String state1 = "";
private String state2 = "";
private String state3 = "";
private String[] state4=null;
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;
}
public String[] getState4() {
return state4;
}
public void setState4(String[] state4) {
this.state4 = state4;
}
public Memento createMemento(){
return new Memento(BeanUtils.backupProp(this));
}
public void restoreMemento(Memento memento){
BeanUtils.restoreProp(this, memento.getStateMap());
}
public String toString(){
return "state1="+state1+"state2="+state2+"state3="+state3+"state4="+state4.length;
}
}
class Memento {
private Map<String, Object> stateMap;
public Memento(Map<String, Object> map){
this.stateMap = map;
}
public Map<String, Object> getStateMap() {
return stateMap;
}
public void setStateMap(Map<String, Object> stateMap) {
this.stateMap = stateMap;
}
}
class BeanUtils {
public static Map<String, Object> backupProp(Object bean){
Map<String, Object> result = new HashMap<String, Object>();
try{
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor des: descriptors){
String fieldName = des.getName();//
Method getter = des.getReadMethod();
Object fieldValue = getter.invoke(bean, new Object[]{});
if(!fieldName.equalsIgnoreCase("class")){
result.put(fieldName, fieldValue);
}
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public static void restoreProp(Object bean, Map<String, Object> propMap){
try {
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor des: descriptors){
String fieldName = des.getName();
if(propMap.containsKey(fieldName)){
Method setter = des.getWriteMethod();
setter.invoke(bean, new Object[]{propMap.get(fieldName)});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Caretaker {
private Map<String, Memento> memMap = new HashMap<String, Memento>();
public Memento getMemento(String index){
return memMap.get(index);
}
public void setMemento(String index, Memento memento){
this.memMap.put(index, memento);
}
}
public class Client {
public static void main(String[] args){
Originator ori = new Originator();//发起者
String[] str = {"飞机"};
ori.setState1("J10");
ori.setState2("J11");
ori.setState3("J20");
ori.setState4(str);
System.out.println("===初始化状态===\n"+ori);
Caretaker caretaker = new Caretaker();//临时替代者
caretaker.setMemento("001",ori.createMemento());//设置备忘录====>备忘录模式关键
String[] str2 = {"软件","职位"};
ori.setState1("项目组长");//修改发起者属性值
ori.setState2("项目经理");
ori.setState3("技术总监");
ori.setState4(str2);
System.out.println("===修改后状态===\n"+ori);
ori.restoreMemento(caretaker.getMemento("001"));//从备忘录中恢复属性值
System.out.println("===恢复后状态===\n"+ori);
}
}
/*注:
*1发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
*2备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
*3管理角色:对备忘录进行管理,保存和提供备忘录。
*/
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
/**
* 设计模式之备忘录模式
*备忘录模式的优点有:
*当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。
*备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。
*
*备忘录模式的缺点:
*在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。
*
*适用场景
*如果有需要提供回滚操作的需求,使用备忘录模式非常适合,比如jdbc的事务操作,文本编辑器的Ctrl+Z恢复等。
*/
class Originator {
private String state1 = "";
private String state2 = "";
private String state3 = "";
private String[] state4=null;
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;
}
public String[] getState4() {
return state4;
}
public void setState4(String[] state4) {
this.state4 = state4;
}
public Memento createMemento(){
return new Memento(BeanUtils.backupProp(this));
}
public void restoreMemento(Memento memento){
BeanUtils.restoreProp(this, memento.getStateMap());
}
public String toString(){
return "state1="+state1+"state2="+state2+"state3="+state3+"state4="+state4.length;
}
}
class Memento {
private Map<String, Object> stateMap;
public Memento(Map<String, Object> map){
this.stateMap = map;
}
public Map<String, Object> getStateMap() {
return stateMap;
}
public void setStateMap(Map<String, Object> stateMap) {
this.stateMap = stateMap;
}
}
class BeanUtils {
public static Map<String, Object> backupProp(Object bean){
Map<String, Object> result = new HashMap<String, Object>();
try{
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor des: descriptors){
String fieldName = des.getName();//
Method getter = des.getReadMethod();
Object fieldValue = getter.invoke(bean, new Object[]{});
if(!fieldName.equalsIgnoreCase("class")){
result.put(fieldName, fieldValue);
}
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
public static void restoreProp(Object bean, Map<String, Object> propMap){
try {
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor des: descriptors){
String fieldName = des.getName();
if(propMap.containsKey(fieldName)){
Method setter = des.getWriteMethod();
setter.invoke(bean, new Object[]{propMap.get(fieldName)});
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Caretaker {
private Map<String, Memento> memMap = new HashMap<String, Memento>();
public Memento getMemento(String index){
return memMap.get(index);
}
public void setMemento(String index, Memento memento){
this.memMap.put(index, memento);
}
}
public class Client {
public static void main(String[] args){
Originator ori = new Originator();//发起者
String[] str = {"飞机"};
ori.setState1("J10");
ori.setState2("J11");
ori.setState3("J20");
ori.setState4(str);
System.out.println("===初始化状态===\n"+ori);
Caretaker caretaker = new Caretaker();//临时替代者
caretaker.setMemento("001",ori.createMemento());//设置备忘录====>备忘录模式关键
String[] str2 = {"软件","职位"};
ori.setState1("项目组长");//修改发起者属性值
ori.setState2("项目经理");
ori.setState3("技术总监");
ori.setState4(str2);
System.out.println("===修改后状态===\n"+ori);
ori.restoreMemento(caretaker.getMemento("001"));//从备忘录中恢复属性值
System.out.println("===恢复后状态===\n"+ori);
}
}
/*注:
*1发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
*2备忘录:负责存储发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。
*3管理角色:对备忘录进行管理,保存和提供备忘录。
*/