【设计模式】19,备忘录模式

(十九)备忘录模式

备忘录模式(Memento Pattern)指在不破坏封装性的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。类似于快照机制。

1,备忘录模式的设计原则

1,发起人(Originator):负责创建一个备忘录,记录自身需要保存的状态;

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

3,备忘录管理员(Caretaker):负责备忘录的管理与创建。

2,简单案例

草稿箱的实现就是一个备忘录的形式,通过草稿箱你可以恢复之前编写的内容,甚至无限次恢复。其实有些场景我们还可以考虑使用数组的形式而非栈,这样我们就可以根据索引回退到指定版本了。

public class Editor {
    
    
    private String title;
    private String content;
    private String img;

	//get,set

    //    保存功能,实际是保存到备忘录
    public ArticleMemento saveToMemento() {
    
    
        ArticleMemento articleMemento = new ArticleMemento(this.title, this.content, this.img);
        return articleMemento;
    }

//    撤销功能就是从栈中取出上一个ArticleMemento对象
    public void undoFromMemento(ArticleMemento articleMemento) {
    
    
        this.title = articleMemento.getTitle();
        this.content = articleMemento.getContent();
        this.img = articleMemento.getImg();
    }

   //全参构造
   //重写tosting
}
public class ArticleMemento {
    
    
    private String title;
    private String content;
    private String img;

    public String getTitle() {
    
    
        return title;
    }

    public String getContent() {
    
    
        return content;
    }

    public String getImg() {
    
    
        return img;
    }
    
	//全参构造
   //重写tosting
    
}
public class DraftBox {
    
    
    private final Stack<ArticleMemento> STACK = new Stack<>();

    public ArticleMemento getMemento() {
    
    
        ArticleMemento articleMemento = null;
//        业务场景一:草稿实时保存,所以撤销指的是回滚到上一版本,并不是上一步。
//        第一次弹栈是当前对象,第二次弹栈是上一个对象。
//        articleMemento = STACK.pop();
//        articleMemento = STACK.pop();

//        业务场景二:及时撤销,用户在不保存的情况下撤销,即回退到上一步。
        articleMemento = STACK.pop();

        return articleMemento;
    }

    public void addMemento(ArticleMemento articleMemento) {
    
    
        STACK.push(articleMemento);
    }
}
public class Client {
    
    
    public static void main(String[] args) {
    
    
        DraftBox draftBox = new DraftBox();
        Editor editor = new Editor("标题1", "备忘录模式", "abc.img");
        ArticleMemento articleMemento = editor.saveToMemento();
        draftBox.addMemento(articleMemento);
        System.out.println(editor.getTitle()+"\t"+editor.getContent()+"\t"+editor.getImg());

        System.out.println("修改标题");
        editor.setTitle("标题2");
        System.out.println("发生了修改后");
//        业务场景一:修改后并保存
       /* articleMemento = editor.saveToMemento();
        draftBox.addMemento(articleMemento);*/
        System.out.println(editor.getTitle()+"\t"+editor.getContent()+"\t"+editor.getImg());

//        测试业务场景一
        articleMemento = draftBox.getMemento();
        editor.undoFromMemento(articleMemento);
        System.out.println("执行撤销指令后");
        System.out.println(editor.getTitle()+"\t"+editor.getContent()+"\t"+editor.getImg());
    }
}
image-20210319090547678

3,备忘录模式的点评

备忘录模式非常适用于需要回滚的业务场景,但是可以看到Memento中需要维护一份操作对象的成员变量,容易造成系统复杂。

猜你喜欢

转载自blog.csdn.net/qq_40589204/article/details/118511820