zoukankan      html  css  js  c++  java
  • 设计模式--备忘录模式

    简介

    ​ 备忘录模式(Memento Pattern)又称为快照模式(Snapshot Pattern)或令牌模式(Token Pattern),是指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态,属于行为型模式。

    ​ 在软件系统中,备忘录模式可以为我们提供一种“后悔药”的机制,他通过存储系统各个历史状态的快照,使得我们可以在任意时刻将系统回滚到某一个历史状态。

    ​ 备忘录模式本质是从发起人实体类(Originator)隔离存储功能,降低实体类的职责。同时由于存储信息(Memento)独立,且存储信息的实体交由管理类(Caretaker)管理,则可以通过为管理类扩展额外的功能对存储信息进行扩展操作(比如增加历史快照功能)。

    备忘录模式的生活场景

    1、git的版本管理

    2、游戏的存档

    备忘录模式适用于以下应用场景:

    1、需要保存历史快照的场景;

    2、希望在对象之外保存状态,且除了自己其他类对象无法访问状态保存具体内容。

    备忘录模式的通用UML类图:

    从UML类图中,我们可以看到,备忘录模式主要包含三种角色:

    发起人角色(Originator):负责创建一个备忘录,记录自身需要保存的状态;具备状态回滚功能;

    备忘录角色(Memento):用于存储Originator的内部状态,且可以防止Originator以外的对象访问;

    备忘录管理角色(Caretaker):负责存储,提供管理备忘录(Memento),无法对备忘录内容进行操作和访问。

    备忘录模式在源码中的体现

    备忘录模式在框架源码中的应用比较少,主要还是需要结合具体的业务场景来使用。

    Spring的webflow源码中StateManageableMessageContext接口

    public interface StateManageableMessageContext extends MessageContext {
    
    	Serializable createMessagesMemento();
    
    	void restoreMessages(Serializable messagesMemento);
    
    	void setMessageSource(MessageSource messageSource);
    }
    

    可以看到这里有一个createMessagesMemento()方法,创建一个消息备忘录。它的实现类:

    public class DefaultMessageContext implements StateManageableMessageContext {
    
    	private static final Log logger = LogFactory.getLog(DefaultMessageContext.class);
    
    	private MessageSource messageSource;
    
    	@SuppressWarnings("serial")
    	private Map<Object, List<Message>> sourceMessages = new AbstractCachingMapDecorator<Object, List<Message>>(
    			new LinkedHashMap<Object, List<Message>>()) {
    
    		protected List<Message> create(Object source) {
    			return new ArrayList<>();
    		}
    	};
        
        ...
    
    	public void clearMessages() {
    		sourceMessages.clear();
    	}
    
    	// implementing state manageable message context
    
    	public Serializable createMessagesMemento() {
    		return new LinkedHashMap<Object, List<Message>>(sourceMessages);
    	}
    
    	@SuppressWarnings("unchecked")
    	public void restoreMessages(Serializable messagesMemento) {
    		sourceMessages.putAll((Map<Object, List<Message>>) messagesMemento);
    	}
    
    	public void setMessageSource(MessageSource messageSource) {
    		if (messageSource == null) {
    			messageSource = new DefaultTextFallbackMessageSource();
    		}
    		this.messageSource = messageSource;
    	}
        ...
    }
    

    我们看到其主要逻辑就相当于是给Message留一个备用,以备恢复之用。

    备忘录模式的优缺点

    优点:

    1、简化发起人实体类(Originator)职责,隔离状态存储或获取,实现了信息的封装,客户端无需关心状态的保存细节;

    2.提供状态回滚功能;

    缺点:

    消耗资源:如果需要保存的状态过多时,每一次保存都会消耗很多内存。

    代码链接

    备忘录模式

  • 相关阅读:
    注释驱动的 Spring cache 缓存介绍--转载
    AOP 的利器:ASM 3.0 介绍
    字符串比较报错
    Performing a thread dump in Linux or Windows--reference
    Linux 精准获取进程pid--转
    /bin/bash^M: bad interpreter: 没有那个文件或目录--转载
    linux 进程综合指令
    Sending e-mail with Spring MVC---reference
    Spring XD 1.1 M2 and 1.0.3 released---support kafka
    大数据框架对比:Hadoop、Storm、Samza、Spark和Flink——flink支持SQL,待看
  • 原文地址:https://www.cnblogs.com/snail-gao/p/15063688.html
Copyright © 2011-2022 走看看