一、什麼是備忘錄模式
Memenoto模式也叫備忘錄模式,是行爲模式之一,它的作用是保存對象的內部狀態,並在需要的時候恢復對象之前的狀態。
(1)、首先我們來寫一個事物回滾的例子
package com.renxin.moshi;
public class Person {
private String name;
private String sex;
private int age;
public Person() {
}
public Person(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void display() {
System.out.println("name:"+name+",sex"+sex+",age"+age);
}
}
創建測試類Test
package com.renxin.moshi;
public class Test {
public static void main(String[] args) {
Person per = new Person("張三","男",30);
//保存內部狀態
Person backup = new Person();
backup.setName(per.getName());
backup.setSex(per.getSex());
backup.setAge(per.getAge());
per.display();
//修改
per.setAge(20);
per.display();
//回滾 還原
per.setName(backup.getName());
per.setSex(backup.getSex());
per.setAge(backup.getAge());
per.display();
}
}
控制檯打印結果爲:
name:張三,sex男,age30
name:張三,sex男,age20
name:張三,sex男,age30
這樣的做法雖然實現了回滾,但是是不合理的!
接下來就引入了java23種設計模式之—–備忘錄模式!
二、備忘錄模式的應用場景:
如果一個對象需要保存狀態並可以通過undo或rollback等操作恢復到以前的狀態時,可以使用Memento模式。
(1)、一個類需要保存他的對象的狀態(相當於Originator角色)
(2)、設計一個類,該類只是用來保存上述對象的狀態(相當於Memenot角色)
(3)、需要的時候,Caretaker角色要求Originator返回一個Memenot並加以保存
(4)、undo或rollback操作時,通過Caretaker保存的Memenot恢復Originator對象的狀態
三、備忘錄模式結構
(1)、創建Memenot
package com.renxin.moshi1;
public class Memenot {
private String name;
private String sex;
private int age;
public Memenot(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
(2)、改造Person類,在最下面加上
//創建一個備份
public Memenot createMemenot() {
return new Memenot(name,sex,age);
}
//恢復備份,也就是還原
public void setMemenot(Memenot menot) {
this.name = menot.getName();
this.sex = menot.getSex();
this.age = menot.getAge();
}
(3)、創建測試類Test
package com.renxin.moshi1;
public class Test {
public static void main(String[] args) {
Person per = new Person("張三","男",20);
//保存內部狀態
Memenot memenot = per.createMemenot();
per.display();
//修改
per.setName("李四");
per.setSex("女");
per.setAge(40);
per.display();
//回滾
per.setMemenot(memenot);
per.display();
}
}
運行結果爲:
name:張三,sex男,age20
name:李四,sex女,age40
name:張三,sex男,age20
四、備忘錄模式的角色和職責:
Origination(原生者這裏指Person):需要被保存狀態以便恢復的那個對象
Memento(備忘錄):改對象由Origination創建,主要用來保存Origination的內部狀態。
Caretaker(管理者):負責在適當的時間保存/恢復Origination對象的狀態
創建管理者,通過管理者來負責恢復;
(1)、創建管理者類
package com.renxin.moshi1;
public class Caretaker {
private Memenot memenot;
public Memenot getMemenot() {
return memenot;
}
public void setMemenot(Memenot memenot) {
this.memenot = memenot;
}
}
(2)、改造測試類Test
package com.renxin.moshi1;
public class Test {
public static void main(String[] args) {
Person per = new Person("張三","男",20);
//保存內部狀態
//Memenot memenot = per.createMemenot();
Caretaker caretaker = new Caretaker();
caretaker.setMemenot(per.createMemenot());
per.display();
//修改
per.setName("李四");
per.setSex("女");
per.setAge(40);
per.display();
//回滾
//per.setMemenot(memenot);
per.setMemenot(caretaker.getMemenot());
per.display();
}
}
舉一個例子:備忘錄應用最經典的的場景,就是在一個闖關遊戲中,比如打到第10關的時候,有事要出去或者想保存第十關好下一次接着從第十關玩,這個時候就需要通過備忘錄模式來保存當前遊戲的狀態!