文章目录
package com.example.demo.designpattern;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态;
* 角色:
* Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,
* 也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。
* Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。
* 备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。
* 需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,
* 原发器的设计在不同的编程语言中实现机制会有所不同。
* Caretaker(负责人/备忘录管理员):它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。
* 在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节
* 应用:快照存盘;撤销操作;事务管理
*/
public class Memento {
private String label;
private String pageName;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getPageName() {
return pageName;
}
public void setPageName(String pageName) {
this.pageName = pageName;
}
}
class OriginatorPage {
private String label;
private String pageName;
private String title;
public void setLabel(String label) {
this.label = label;
}
public void setPageName(String pageName) {
this.pageName = pageName;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "OriginatorPage{" +
"label='" + label + '\'' +
", pageName='" + pageName + '\'' +
'}';
}
public Memento createMemento(){
Memento memento = new Memento();
memento.setLabel(this.label);
memento.setPageName(this.pageName);
return memento;
}
public void restoreMemento(Memento memento){
this.setLabel(memento.getLabel());
this.setPageName(memento.getPageName());
}
}
class MementoCaretaker {
public volatile AtomicInteger index = new AtomicInteger(-1);
private ArrayList<Memento> mementoList = new ArrayList<>();
public Memento getMemento(int i) {
return mementoList.get(i);
}
public void addMemento(Memento memento) {
index.incrementAndGet();
mementoList.add(memento);
}
}
class BrowserClient {
public static void main(String[] args) {
OriginatorPage page = new OriginatorPage();
page.setPageName("123");
page.setLabel("www.123.com");
page.setTitle("123");
href(page);
page.setPageName("456");
page.setLabel("www.456.com");
page.setTitle("456");
href(page);
back(page);
forward(page);
}
private static MementoCaretaker mementoCaretaker = new MementoCaretaker();
public static void href(OriginatorPage page) {
mementoCaretaker.addMemento(page.createMemento());
System.out.println(page);
}
public static void back(OriginatorPage page) {
int i = mementoCaretaker.index.decrementAndGet();
if (i < 0) {
System.out.println("no-history");
return;
}
page.restoreMemento(mementoCaretaker.getMemento(i));
System.out.println("back-to:" + page);
}
public static void forward(OriginatorPage page) {
Memento memento = mementoCaretaker.getMemento(mementoCaretaker.index.incrementAndGet());
if (memento == null) {
System.out.println("nothing-to-forward");
return;
}
page.restoreMemento(memento);
System.out.println("forward-to:" + page);
}
}