zoukankan      html  css  js  c++  java
  • Memento模式

    一、Memento模式的目的:

    memento是一个保存另外一个对象内部状态拷贝的对象.这样以后就可以将该对象恢复到原先保存的状态.

    二、Memento模式的简单例子:

    下面的例子来源于Jdon网站的《GoF设计模式系列》的《Memento模式》,虽然简单却形象地表明了Memento模式的应用

    Java代码  收藏代码
    1. package memento;  
    2.   
    3. import java.io.File;  
    4.   
    5. public class Originator {  
    6.       
    7.     private int number;   
    8.     private File file = null;  
    9.       
    10.     public Originator(){  
    11.           
    12.     }  
    13.       
    14.     // 创建一个Memento,将自身作为参数传入  
    15.     public Memento getMemento(){  
    16.         return new Memento(this);  
    17.     }  
    18.       
    19.     //从Memento中取出保存的数据,恢复为原始状态  
    20.     public void setMemento(Memento m){  
    21.         number = m.getNumber();  
    22.         file = m.getFile();  
    23.     }  
    24.   
    25.     public int getNumber() {  
    26.         return number;  
    27.     }  
    28.   
    29.     public void setNumber(int number) {  
    30.         this.number = number;  
    31.     }  
    32.   
    33.     public File getFile() {  
    34.         return file;  
    35.     }  
    36.   
    37.     public void setFile(File file) {  
    38.         this.file = file;  
    39.     }     
    40. }  
    Java代码  收藏代码
    1. package memento;  
    2.   
    3. import java.io.File;  
    4. import java.io.Serializable;  
    5.   
    6. public class Memento implements Serializable {  
    7.       
    8.     private int number;  
    9.     private File file = null;  
    10.       
    11.     public Memento(Originator o){  
    12.         this.number = o.getNumber();  
    13.         this.file = o.getFile();  
    14.     }  
    15.   
    16.     public int getNumber() {  
    17.         return this.number;  
    18.     }  
    19.   
    20.     public void setNumber(int number) {  
    21.         this.number = number;  
    22.     }  
    23.   
    24.     public File getFile() {  
    25.         return this.file;  
    26.     }  
    27.   
    28.     public void setFile(File file) {  
    29.         this.file = file;  
    30.     }  
    31.       
    32.       
    33. }  

    三、Memento模式的特点:

    在需要提供保存、恢复对象状态的类中,必须提供两个方法:

    .保存对象当前状态方法:将对象自身(this)作为参数传入,创建备忘录。
    .恢复对象之前状态的方法:取出备忘录/接收一个备忘录对象,从中获取对象之前的状态

    模式的缺点是耗费大,如果内部状态很多,再保存一份,无意要浪费大量内存.

    注意:Memento模式保存的是操作前对象的状态,而不是操作后对象的状态;否则就没办法做恢复了

    一、“Mementor”模式和“堆栈”的结合-“GUI界面撤销功能”的实现

    ·当用户在面板中拖动一个组件到编辑区时,应用程序为编辑区创建一个备忘录,并把它加入到一个堆栈中(注意此时备忘录中包含的是操作前的状态,而非操作后的状态)

    ·当用户单击“撤销”按钮时,应用程序就将堆栈顶部的备忘录弹出,然后将编辑区恢复为该备忘录所记录的状态

    当可视化应用程序启动后,首先向空的堆栈中压入一个初始的空备忘录,并且保证绝对不会将该备忘录从栈中弹出,从而确保该栈的顶部总是有一个有效的备忘录。当栈中仅包含一个备忘录的时候,应用程序应当禁用“撤销”按钮

    二、“Mementor”模式和“Observer”模式的结合-“通知式恢复”

    在某些情况下,我们希望为GUI组件注册一些监听器,当组件的状态发生改变时,可以通知所有对它感兴趣的监听器,这种情况我们可以用“Observer”模式来实现。

    还是以我们上面的例子来说:假如用户从面板中拖动一个组件到编辑区后,有几个监听器对它感兴趣,并且采取了相应的操作,现在用户单击了“撤销”按钮,那么我们应该把这个事件通知所有监听器,告诉他们必须恢复之前所有的状态。这种情况就可以把两种模式结合起来使用:

    ·当对象被创建时,激活并为该对象注册监听器(观察着),监听器创建一个初始化备忘录,保存编辑区的原始信息
    ·当对象(被观察着)被销毁(用户单击“撤销”按钮时),向所有注册的监听器发送信息
    ·监听器(观察者)接收到信息,从备忘录中取出编辑区信息的备忘录,恢复当前编辑区的状态

    三、“Mementor”模式和“Observer”模式、“责任链”模式的结合-“链式通知恢复”

    在上面我们提到了将“Mementor”模式和“Observer”模式结合起来达到到“通知式恢复”的效果,考虑下面一个情况:

    如果我们在安装一个软件或执行一个长时间、多次交互的情况,加入用户在最后一个操作中选择了“取消”操作,我们应该怎么做呢?

    我的想法是在为每一次操作创建一个备忘录,并将其放在“责任链”上,当最后用户选择取消时,沿着这条“责任链”一个个通知观察者,由观察者取出备忘录,执行恢复工作。

    注意:这个方法和第二个方法有点区别:第二个方法不管恢复的顺序,而第三种方法适合讲究恢复顺序的情况,例如前面提到的软件安装的撤销。

    四、“Mementor”模式和“Flyweight”模式的结合:减少相同对象的拷贝

    用于保存对象状态的“备忘录”对象,必须拥有一份和被保存对象相同的属性拷贝。

    对于“备忘录”有可能导致内存消耗过大的情况,如果对象中的属性是“公用的”(即多个对象可以共享一个属性),那么我们可以考虑采用“享元模式”,减少相同属性对象的创建。但是这个方法对于属性多为运行时确定的情况作用不大。

  • 相关阅读:
    Python之黏包
    Python的subprocess模块
    (经典)TCP粘包分析
    python--数据类型bytes
    python socket编程
    Python之模块和包
    Memcache的客户端连接系列(二) Python
    Memcache的客户端连接系列(一) Java
    Stunnel客户端安装和配置
    分布式数据库中间件的实现原理介绍四:平滑扩容
  • 原文地址:https://www.cnblogs.com/duanxz/p/2660419.html
Copyright © 2011-2022 走看看