zoukankan      html  css  js  c++  java
  • 公用技术——设计模式16——行为型模式——备忘录模式

    1、概念

    备忘录模式记录对象的所有历史状态,这样做的目的是对象可以回滚到之前的任何一种历史状态。

    备忘录模式涉及到三个角色

    • 核心对象:在对象的生命周期中,伴随着状态的改变。
    • 历史状态对象:它对应核心对象的某一个历史状态。
    • 历史状态管理对象:它用于执行保存,回溯历史状态等操作。

    备忘录模式的示例随处可见,例如事务的回滚,电脑的撤销操作等。

    2、UML图

    • CoreObject扮演着核心对象的角色,它拥有属性state。
    • History对象扮演着历史状态对象的角色,保存着某一个历史状态
    • HistoryManage对象扮演着历史状态管理对象的角色,用于保存,回溯历史状态等操作。

    History对象可以拥有state属性,也可以把整个对象作为属性,需要注意的是CoreObject对象作为属性时,它保存的不是引用,而是对象本身。不要犯多个引用指向同一个CoreObject对象的错误

    3、代码

    3.1 CoreObject

    /**
     * 
     * @File Name: CoreObject.java
     * @Description: 扮演者核心对象的角色,在其生命周期中会存在各种状态。
     * @version 1.0
     * @since JDK 1.8
     */
    public class CoreObject {
    	// 状态属性
    	private String state;
    	// get 和 set 省略
    }
    

    3.2 History

    /**
     * 
     * @File Name: History.java
     * @Description: 对应CoreObject的某一种历史状态
     * @version 1.0
     * @since JDK 1.8
     */
    public class History {
    	// 这里也可以保存state属性,它是必备属性
    	private CoreObject core;
    
    	// private String state;
    	public History(CoreObject core) {
    		this.core = core;
    	}
    	
    	// get 和 set 方法, 本质上不应该提供set方法,设置之后,不允许在修改。
    }
    

    3.3 HistoryManage

    /**
     * 
     * @File Name: HistoryManage.java 
     * @Description: 扮演着管理历史状态的角色,执行保存,回滚等基本操作
     * @version 1.0
     * @since JDK 1.8
     */
    public class HistoryManage {
    	// 历史状态
    	private static List<History> historys = new LinkedList<History>();
    
    	public static void save(History history) {
    		historys.add(history);
    	}
    
    	public static CoreObject revert(History history) {
    		return history2core(history);
    	}
    
    	// 将核心对象转换为历史对象
    	public static History core2History(CoreObject core) {
    		return new History(core);
    	}
    
    	// 将历史对象转换为核心对象
    	public static CoreObject history2core(History history) {
    		return history.getCore();
    	}
    }
    

    4、讨论

      问题1:History对象与CoreObject对象之间的关系?

      答:CoreObject对象与History对象是一种关联关系,1个CoreObject拥有多个History对象,每个History对象记录着CoreObject的一种历史状态。

      问题2:History对象有个数限制吗?

      答:在理论上History对象没有个数限制,但是在实际情况中,可以添加限制,因为过多的历史状态没有意义,而且会影响性能。

      当无限制时,建议在HistoryManage中使用LinkedList方式保存History对象,并限制只能回滚到前一种状态。因为链式结构在访问对象时,都需要遍历之前的对象,所以当History对象过多时,支持回滚到任意一种历史状态会影响性能。

      当有限制时,建议在HistoryManage中使用Stack方式保存History对象,并指定size为限制的个数。每次回滚使用stack的pop操作。

      问题3:保存的历史状态是否可以重复?

      答: 由核心对象决定。某些核心对象在生命周期中只有有限的几种状态,例如线程对象,它有就绪态,阻塞状态,运行状态,等待状态,死亡状态。某些操作会导致从一个状态转换为另外一种状态,但是这些状态是可以重复的,一个线程是可以多次进入阻塞状态的,而有些状态是不能重复的,例如死亡状态。

    5、示例

      用户浏览网页的历史记录。

  • 相关阅读:
    redis(二)高级用法
    redis(一) 安装以及基本数据类型操作
    RabbitMQ(五) -- topics
    JS实时数据运算
    Access数据库中Sum函数返回空值(Null)时如何设置为0
    asp检测数字类型函数
    MVC:从客户端中检测到有潜在危险的 Request.Form 值 的解决方法
    WIN8系统安装软件时提示"扩展属性不一致"的解决方法
    免费的网络扫描器-Advanced IP Scanner
    中国电信大亚DP607光猫破解,设置路由,wifi!关闭远程管理,改连接限制,SN码查询!
  • 原文地址:https://www.cnblogs.com/rain144576/p/9940876.html
Copyright © 2011-2022 走看看