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

来源:互联网 发布:ug8.0编程手机教程 编辑:程序博客网 时间:2024/06/10 13:59

概要:

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

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:双接口设计:考虑对象安全问题,可以提供两个接口。一个是业务正常接口,实现必要的业务逻辑,叫宽接口。另一个接口是空接口,什么方法都没有,目的是提供给子系统外的模块访问,叫窄接口,窄接口相对安全