您的位置:首页 > 编程语言 > Java开发

java设计模式之备忘录

2018-01-19 16:28 417 查看

一.简介

话说,我小时候玩小霸王游戏中坦克大战的闯关游戏中,哪个时候我们基本上每次过了一关都会保存进度,如果不玩了,或者是下一关太难过了每过了,这样我们就可以回到原先的时候,回到原先的进度继续游戏.这样我们就回到过去了.

二.结构

备忘录(Memento)角色:备忘录角色存储"备忘发起者角色"的内部状态;在黑箱和自述历史模式的情况下,不允许除了发起人之外的人访问自己.
备忘发起者角色:创建一个备忘录,在需要还原的时候,还原备忘录内部状态;
备忘录管理者角色:负责保存好备忘录.

三.代码

白箱,外部可以访问,简单而言,就是没有进行封装.

public class Memorandum {

public static void main(String[] args) {
// 发起者
Sponsor sponsor = new Sponsor();
// 管理者
Manager manager = new Manager();

// 设置内容
sponsor.setText("abc");
// 记录版本
sponsor.createManager(manager, 1);
// 修改内容
sponsor.setText("abcdef");
// 记录版本
sponsor.createManager(manager, 2);

// 修改内容
sponsor.setText("abcdefgh");
// 记录版本
sponsor.createManager(manager, 3);

// 回滚到版本1
sponsor.callBackToVersion(manager, 1);
System.out.println("第一个版本的内容是:" + sponsor.getText());
// 回滚到版本2
sponsor.callBackToVersion(manager, 2);
System.out.println("第一个版本的内容是:" + sponsor.getText());
}
}

// 操作角色 文本编辑
class TextEdit {
private String text;

public String getText() {
return text;
}

publ
4000
ic void setText(String text) {
this.text = text;
}
}
// 管理者
class Manager {
private Map<Integer, TextEdit> map = new HashMap<>();

public TextEdit getTextEdit(Integer version) {
return map.get(version);
}

// 每次取出最新的版本
public void setTextEdit(TextEdit baby, Integer version) {
map.put(version, baby);
}
}
// 发起者
class Sponsor {
private String text;
// 保存状态
public Manager createManager(Manager manager, Integer version) {
TextEdit edit = new TextEdit();
edit.setText(text);
manager.setTextEdit(edit, version);
return manager;
}
// 回滚到指定版本
public void callBackToVersion(Manager manager, Integer version) {
text = manager.getTextEdit(version).getText();
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}
}
//output
//第一个版本的内容是:abc
//第一个版本的内容是:abcdef
黑箱,外部不能操作备忘录角色,它更符合我们编程的开闭原则,对外开放访问,关闭修改.只有发起人才能对备忘角色进行修改,管理者或者是其他类不能对备忘录角色进行修改.


public class Memorandum {

public static void main(String[] args) {
// 发起者
Sponsor sponsor = new Sponsor();
// 管理者
Manager manager = new Manager();

// 设置内容
sponsor.setText("abc");
// 记录版本
sponsor.createManager(manager, 1);
// 修改内容
sponsor.setText("abcdef");
// 记录版本
sponsor.createManager(manager, 2);
// 修改内容
sponsor.setText("abcdefgh");
// 记录版本
sponsor.createManager(manager, 3);

// 回滚到版本1
sponsor.callBackToVersion(manager, 1);
System.out.println("第一个版本的内容是:" + sponsor.getText());
// 回滚到版本2
sponsor.callBackToVersion(manager, 2);
System.out.println("第一个版本的内容是:" + sponsor.getText());

}

}

// 定义接口,让备忘录角色实现,此接口为了让管理者去操作
interface A {}
// 管理者 它不能看到备忘录角色的具体的内容,因为它操作的是接口
class Manager {
private Map<Integer, A> map = new HashMap<>();

public A getTextEdit(Integer version) {
return map.get(version);
}

// 每次取出最新的版本
public void setTextEdit(A baby, Integer version) {
map.put(version, baby);
}
}

// 发起者 能知道备忘录角色的具体类容,因为备忘录角色是它的私有类
class Sponsor {
private String text;
// 保存状态
public Manager createManager(Manager manager, Integer version) {
TextEdit edit = new TextEdit(text);
manager.setTextEdit(edit, version);
return manager;
}
// 回滚到指定版本
public void callBackToVersion(Manager manager, Integer version) {
text = ((TextEdit) manager.getTextEdit(version)).getText();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
// 备忘录角色,实现了窄接口
// 注意:此类的所有属性都是私有
private class TextEdit implements A {
private String text;
private TextEdit(String text) {
this.text = text;
}
private String getText() {
return text;
}

private void setText(String text) {
this.text = text;
}
}
}
// output
//第一个版本的内容是:abc
//第一个版本的内容是:abcdef
自述历史模式,此模式把负责人和发起人放到一个类中,这是在开发中使用的最常用的



public class Memorandum {

public static void main(String[] args) {
// 发起人与负责人
Sponsor sponsor = new Sponsor();
// 设置内容
sponsor.setText("abc");
// 记录版本
sponsor.createManager(1);
// 修改内容
sponsor.setText("abcdef");
// 记录版本
sponsor.createManager(2);
// 修改内容
sponsor.setText("abcdefgh");
// 记录版本
sponsor.createManager(3);

// 回滚到版本1
sponsor.callBackToVersion(1);
System.out.println("第一个版本的内容是:" + sponsor.getText());
// 回滚到版本2
sponsor.callBackToVersion(2);
System.out.println("第一个版本的内容是:" + sponsor.getText());

}

}

// 发起者+负责人 能知道备忘录角色的具体类容,因为备忘录角色是它的私有类
class Sponsor {
private String text;

private Map<Integer, TextEdit> map = new HashMap<>();

//    每次取出最新的版本
private TextEdit getTextEdit(Integer version) {
return map.get(version);
}

// 保存版本
private void setTextEdit(TextEdit baby, Integer version) {
map.put(version, baby);
}

// 保存状态
public void createManager(Integer version) {
TextEdit edit = new TextEdit(text);
setTextEdit(edit, version);
}

// 回滚到指定版本
public void callBackToVersion(Integer version) {
text = getTextEdit(version).getText();
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

// 备忘录角色,被发起者私有
// 注意:此类的所有属性都是私有
private class TextEdit {
private String text;

private TextEdit(String text) {
this.text = text;
}
private String getText() {
return text;
}
}
}
// output
//第一个版本的内容是:abc
//第一个版本的内容是:abcdef


四.应用场景

必须保存某一个对象某个或者多个时刻的状态,以方便我们以后使用的时候回复到以前的状态;
如果用一个接口让其他对象直接得到这些状态,江湖暴露对象的实现细节并且破环对象的封装型.

五.各个角色的作用

备忘录角色:将发起人角色的内部状态存储下来,备忘录能根据发起人判断应该存储多少备忘录.能保护内容不被发起人之外的对象读取;
发起人角色:创建一个含有当前内部状态的备忘录角色,使用备忘录角色存储其内部状态;
负责人角色:保存备忘录角色;

六.参考文献

大话设计模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: