[设计模式]备忘录模式

1. 定义

  在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。

  一个备忘录是一个对象,它存储另一个对象在某个瞬间的内部状态,后者被称为备忘录的原发器。

2. 类图

  

  Memento: 备忘录。主要用来存储原发器对象的内部状态,但是具体需要存储哪些数据是由原发器对象来决定的。另外备忘录应该只能由原发器对象来访问它内部的数据,原发器外部的对象不应该访问到备忘录对象的内部数据。

  Originator:原发器。使用备忘录来保存某个时刻原发器自身的状态,也可以使用备忘录来恢复内部状态。

  Caretaker:备忘录管理者,或者成为备忘录负责人。主要负责保存备忘录对象,但是不能对备忘录对象的内容进行操作或检查。

3. 实例

  

package com.jerry.designpattern.demo;
/**
 * 备忘录接口
 * @author Jerry
 * @date 2015年2月1日 下午9:18:38
 */
public interface FlowAMockMemento {

}

package com.jerry.designpattern.demo;

import java.io.Serializable;

/**
 * 
 * @author Jerry
 * @date 2015年2月1日 下午9:21:32
 */
public class FlowAMock implements Serializable{
    /**
     * 流程名称
     */
    private String flowName;
    
    private int tempResult;
    private String tempState;
    
    public FlowAMock(String flowName) {
        this.flowName = flowName;
    }
    
    public void runPhaseOne() {
        this.tempResult = 3;
        this.tempState = "phase one";
    }
    
    public void schema1() {
        this.tempState += ", schema1";
        System.out.println(this.tempState + ",now run:" + this.tempResult);
        this.tempResult += 11;
    }
    
    public void schema2() {
        this.tempState += ", schema2";
        System.out.println(this.tempState + ",now run:" + this.tempResult);
        this.tempResult += 22;
    }
    
    public FlowAMockMemento createMemento() {
        return new MementoImpl(this.tempResult, this.tempState);
    }
    
    public void setMemento(FlowAMockMemento memento) {
        MementoImpl mementoImpl = (MementoImpl)memento;
        this.tempResult = mementoImpl.getTempResult();
        this.tempState = mementoImpl.getTempState();
    }
    
    private class MementoImpl implements FlowAMockMemento, Serializable {
        private int tempResult;
        private String tempState;
        
        public MementoImpl(int tempResult, String tempState) {
            this.tempResult = tempResult;
            this.tempState = tempState;
        }
        
        public int getTempResult() {
            return tempResult;
        }
        
        public String getTempState() {
            return tempState;
        }
    }
}

package com.jerry.designpattern.demo;
/**
 * 
 * @author Jerry
 * @date 2015年2月1日 下午9:41:43
 */
public class FlowAMockCareTaker {
    
    private FlowAMockMemento memento;
    
    public void saveMemento(FlowAMockMemento memento) {
        this.memento = memento;
    }
    
    public FlowAMockMemento retrieveMemento() {
        return this.memento;
    }
}

package com.jerry.designpattern.demo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 将对象保存到文件中
 * @author Jerry
 * @date 2015年2月1日 下午10:38:39
 */
public class FlowAMockFileCareTaker {
    public void saveMemento(FlowAMockMemento memento) {
        ObjectOutputStream output = null;
        try {
            output = new ObjectOutputStream(
                                            new BufferedOutputStream(
                                                    new FileOutputStream("FileMemento")));
            output.writeObject(memento);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                output.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                output = null;
            }
        }
    }
    
    public FlowAMockMemento retrieveMemento() {
        FlowAMockMemento memento = null;
        ObjectInputStream in = null;
        try {
            in = new ObjectInputStream(
                    new BufferedInputStream(
                            new FileInputStream("FileMemento")));
            memento = (FlowAMockMemento) in.readObject();
        } catch (Exception e) {
            // TODO: handle exception
            try {
                in.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                in = null;
            }
        }
        return memento;
    }
}

package com.jerry.designpattern.demo;
/**
 * 
 * @author Jerry
 * @date 2015年2月1日 下午9:53:10
 */
public class Client {
    public static void main(String[] args) {
        FlowAMock mock = new FlowAMock("TestFlow");
        mock.runPhaseOne();
        
        //FlowAMockCareTaker careTaker = new FlowAMockCareTaker();
        FlowAMockFileCareTaker careTaker = new FlowAMockFileCareTaker();
        careTaker.saveMemento(mock.createMemento());
        
        mock.schema1();
        mock.setMemento(careTaker.retrieveMemento());
        mock.schema2();
    }
}


4. 优缺点

  优点:更好的封装性,简化了原发器,引入窄接口和款接口。

  缺点:可能导致高开销。

原文地址:https://www.cnblogs.com/jerry19890622/p/4267167.html