《设计模式之禅》-多状态的备忘录模式

一个javabean一般来说会有多个状态如果用之前的方法,就得写一大堆备份语句这显然是不现实也不可取的那么 我们可以用内省的方法进行bean的属性备份和还原,我们使用HashMap来进行存储状态

发起人(javabean)

public class Originator {
    private String state1 = "";
    private String state2 = "";
    private String state3 = "";


    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 "状态1:"+state1+",状态2:"+state2+",状态3:"+state3;
    }
    
}

备忘录角色

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;
    }
}

 备忘录管理员角色

public class Caretaker {
    //备忘录角色
    private Memento memento;
    public void setMemento(Memento memento){
        this.memento = memento;
    }

    public Memento getMemento() {
        return memento;
    }
}

多状态备份的核心代码

主要是用到了内省的方法,

1.先通过getClass()方法获得内存中bean对象

2.然后通过Introspector.getBeanInfo 将得到的BeanInfo对象封装了把这个类当做JavaBean看的结果信息,即属性的信息

3.通过getPropertyDescriptors(),获得属性的描述,有三个

4.每个PropertyDescriptor包含以下信息

 

 5.读取属性信息用getReadMethod() 返回一个method对象

6.然后使用invoke方法执行该方法相当于bean.getState1();

7.然后保存状态信息

public class BeanUtils {
    public static HashMap<String, Object> backupProp(Object bean) {
        HashMap<String, Object> result = new HashMap<String, Object>();
        try {
            //获得bean描述 bean.getClass 获得内存中bean的Class类型对象
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(),Object.class);
            //getPropertyDescriptors(),获得属性的描述,可以采用遍历propertyDescriptors的方法,来查找、设置类的属性。
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            //遍历所有属性 包含了 属性的名字,读写方法
            for (PropertyDescriptor des : propertyDescriptors) {
                //属性名称
                String fieldName = des.getName();
                //getReadMethod(),获得用于读取属性值的方法
                Method getter = des.getReadMethod();
                //读取属性值 bean 是哪个类执行,new Object[]{}是参数 getter是执行哪个方法
                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, HashMap<String, Object> propMap) {
        //获得bean描述
        try {
            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) {
            e.printStackTrace();
        }
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值