JAVA的23种设计模式---备忘录模式(二)

概要:

该文章参考了《设计模式之禅》一书及一些前辈的博客文章

1.该文章阐述了备忘录模式的基础原理及示例代码;
2.该文章适合初学设计模式的技术人员研习;
3.该文章有许多不足之处,请各位大咖指正,喷子绕道;
4.该文章是《JAVA的23种设计模式—备忘录模式(一)》的续写,点此跳转到第一部分

正文:

4.多状态的备忘录模式示例代码实现:

package com.csdn;
/**
 * 发起人角色
 * @author Administrator
 *
 */
public class Originator {
    //内部状态
    private String state1;
    private String state2;
    private String state3;
    //getter、setter
    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 Memento createMemento(){
        return new Memento(BeanUtils.backupProp(this));
    }
    //恢复备份
    public void restoreMemento(Memento _memento){
        BeanUtils.restoreProp(this,_memento.getStateMap());
    }
    @Override
    public String toString() {
        return "Originator [state1=" + state1 + ", state2=" + state2 + ", state3=" + state3 + "]";
    }
}
package com.csdn;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;

/**
 * 工具类
 * @author Administrator
 *
 */
public class BeanUtils {
    //bean所有属性和数值放入到Hashmap中
    public static HashMap<String,Object> backupProp(Object bean){
        HashMap<String,Object> result = new HashMap<String,Object>();
        try {
            //获得bean描述
            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;
    }
    //Hashmap的值返回到bean中
    public static void restoreProp(Object bean,HashMap<String, Object> propMap){
        try {
            //获得bean描述
            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();
        }
    }
}
package com.csdn;

import java.util.HashMap;
/**
 * 备忘录角色
 * @author Administrator
 *
 */
public class Memento {
    //接受HashMap作为状态
    private HashMap<String,Object> stateMap;
    //接受一个对象,建立一个备份
    public Memento(HashMap<String,Object> map){
        this.stateMap = map;
    }
    public HashMap<String, Object> getStateMap() {
        return stateMap;
    }
    public void setStateMap(HashMap<String, Object> stateMap) {
        this.stateMap = stateMap;
    }   
}
package com.csdn;

/**
 * 备忘录管理者角色
 * @author Administrator
 *
 */
public class Caretaker {
    //备忘录对象
    private Memento memento;
    //getter、setter
    public Memento getMemento() {
        return memento;
    }
    public void setMemento(Memento memento) {
        this.memento = memento;
    }   
}
package com.csdn;
/**
 * 场景类
 * @author Administrator
 *
 */
public class Client {
    public static void main(String[] args) {
        //定义发起人
        Originator originator = new Originator();
        //定义备忘录管理员
        Caretaker caretaker = new Caretaker();
        //初始化
        originator.setState1("a");
        originator.setState2("b");
        originator.setState3("c");
        System.out.println("初始化状态:"+originator);
        //备份
        caretaker.setMemento(originator.createMemento());
        //修改状态值
        originator.setState1("aa");
        originator.setState2("bb");
        originator.setState3("cc");
        System.out.println("修改后状态:"+originator);
        //恢复备份数据
        originator.restoreMemento(caretaker.getMemento());
        System.out.println("恢复后状态:"+originator);
    }
}

输出:

初始化状态:Originator [state1=a, state2=b, state3=c]
修改后状态:Originator [state1=aa, state2=bb, state3=cc]
恢复后状态:Originator [state1=a, state2=b, state3=c]

注:
a:该示例实现了一个JavaBean对象(多个属性)的所有状态的备份及还原

5.多备份的备忘录模式示例代码实现(在第四个示例上进行修改):

package com.csdn;

import java.util.HashMap;

/**
 * 备忘录管理者角色
 * @author Administrator
 *
 */
public class Caretaker {
    //容纳备忘录的容器
    private HashMap<String, Memento> mementoMap = new HashMap<String, Memento>();
    public Memento getMemento(String idx) {
        return mementoMap.get(idx);
    }
    public void setMemento(String idx,Memento memento) {
        this.mementoMap.put(idx, memento);
    }   
}
package com.csdn;
/**
 * 场景类
 * @author Administrator
 *
 */
public class Client {
    public static void main(String[] args) {
        //定义发起人
        Originator originator = new Originator();
        //定义备忘录管理员
        Caretaker caretaker = new Caretaker();
        //初始化并备份
        originator.setState1("a");
        originator.setState2("b");
        originator.setState3("c");
        System.out.println("初始化状态:"+originator);
        caretaker.setMemento("001",originator.createMemento());
        //修改状态值并备份
        originator.setState1("aa");
        originator.setState2("bb");
        originator.setState3("cc");
        System.out.println("修改后状态:"+originator);
        caretaker.setMemento("002",originator.createMemento());
        //恢复初始的备份数据
        originator.restoreMemento(caretaker.getMemento("001"));
        System.out.println("恢复初始备份数据后的状态:"+originator);
        //恢复修改后备份的数据
        originator.restoreMemento(caretaker.getMemento("002"));
        System.out.println("恢复修改后备份数据后的状态:"+originator);
    }
}

输出:

初始化状态:Originator [state1=a, state2=b, state3=c]
修改后状态:Originator [state1=aa, state2=bb, state3=cc]
恢复初始备份数据后的状态:Originator [state1=a, state2=b, state3=c]
恢复修改后备份数据后的状态:Originator [state1=aa, state2=bb, state3=cc]

注:
a:只修改了备忘录管理员类的代码,使得该类中的容器可以存多个备忘录,就可以实现多备份
b:建议增加Map上限,防止内存溢出

6.更好封装备忘录示例代码实现(在第四、五个示例上进行修改):

package com.csdn;
/**
 * 备忘录空接口
 * @author Administrator
 *
 */
public interface IMemento {

}
package com.csdn;

import java.util.HashMap;

/**
 * 发起人角色
 * @author Administrator
 *
 */
public class Originator {
    //内部状态
    private String state1;
    private String state2;
    private String state3;
    //getter、setter
    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 IMemento createMemento(){
        return new Memento(BeanUtils.backupProp(this));
    }
    //恢复备份
    public void restoreMemento(IMemento _imemento){
        BeanUtils.restoreProp(this,((Memento)_imemento).getStateMap());
    }
    @Override
    public String toString() {
        return "Originator [state1=" + state1 + ", state2=" + state2 + ", state3=" + state3 + "]";
    }

    /**
     * 内置类
     * @author Administrator
     *
     */
    private class Memento implements IMemento{
        //接受HashMap作为状态
        private HashMap<String,Object> stateMap;
        //接受一个对象,建立一个备份
        private Memento(HashMap<String,Object> map){
            this.stateMap = map;
        }
        private HashMap<String, Object> getStateMap() {
            return stateMap;
        }
        private void setStateMap(HashMap<String, Object> stateMap) {
            this.stateMap = stateMap;
        }
    }
}
package com.csdn;

import java.util.HashMap;

/**
 * 备忘录管理者角色
 * @author Administrator
 *
 */
public class Caretaker {
    //容纳备忘录的容器
    private HashMap<String, IMemento> mementoMap = new HashMap<String, IMemento>();
    public IMemento getMemento(String idx) {
        return mementoMap.get(idx);
    }
    public void setMemento(String idx,IMemento memento) {
        this.mementoMap.put(idx, memento);
    }   
}

注:
a:该示例场景类与输出结果与示例五一致
b:该示例删除了独立的备忘录Memento类,在发起人角色类中增加内置的private Memento备忘录类,并且其实现了IMemento空接口,只有发起者可以访问它,其他类都不可以访问,外界想与备忘录产生关联关系需通过IMemento接口,保证了备忘录的安全
c:双接口设计:考虑对象安全问题,可以提供两个接口。一个是业务正常接口,实现必要的业务逻辑,叫宽接口。另一个接口是空接口,什么方法都没有,目的是提供给子系统外的模块访问,叫窄接口,窄接口相对安全

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值