【設計模式】備忘錄模式
阿新 • • 發佈:2018-12-10
備忘錄模式
在不破壞封裝性的前提下,補貨一個物件的內部狀態,並在改物件之外儲存這個狀態,這樣就可以將現在的狀態恢復到原先儲存的狀態。
模型圖
程式碼
public class Originator { private String state="on"; private Memento memento=null; public Memento getMemento() { return new Memento(state); } public void setMemento(Memento memento) { this.state=memento.getState(); } public String getState() { return state; } public void setState(String state) { this.state = state; } public void showState(){ System.out.println("狀態:="+this.state); } }
public class Memento {
private String state="on";
public Memento(String state) {
this.state=state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class CareTaker { private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } }
public class Test { public static void main(String[] args) { Originator originator=new Originator(); originator.setState("on"); originator.showState(); CareTaker careTaker=new CareTaker(); careTaker.setMemento(originator.getMemento()); originator.setState("off"); originator.showState(); originator.setMemento(careTaker.getMemento()); originator.showState(); } }
案例 模擬遊戲角色生命存檔
分析設計 通過備忘錄模式進行存檔
模型圖
public class RoleGame {
//生命力
private int live;
//法力
private int atk;
//攻擊力
private int hit;
private RoleStateMemento roleStateMemento=null;
public RoleStateMemento getRoleStateMemento() {
return new RoleStateMemento(live,atk,hit);
}
public void setRoleStateMemento(RoleStateMemento roleStateMemento) {
this.live=roleStateMemento.getLive();
this.atk=roleStateMemento.getAtk();
this.hit=roleStateMemento.getHit();
}
public int getLive() {
return live;
}
public void setLive(int live) {
this.live = live;
}
@Override
public String toString() {
return "RoleGame [live=" + live + ", atk=" + atk + ", hit=" + hit+"]";
}
public int getAtk() {
return atk;
}
public RoleGame(int live, int atk, int hit) {
super();
this.live = live;
this.atk = atk;
this.hit = hit;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getHit() {
return hit;
}
public void setHit(int hit) {
this.hit = hit;
}
public void show(){
System.out.println(toString());
}
}
public class RoleGameCareTaker {
Map<String,RoleStateMemento> memen=new ConcurrentHashMap<String, RoleStateMemento>();
public void savePro(String key,RoleStateMemento value){
memen.put(key, value);
}
public RoleStateMemento readPro(String key){
return memen.get(key);
}
}
public class RoleStateMemento {
public RoleStateMemento(int live, int atk, int hit) {
super();
this.live = live;
this.atk = atk;
this.hit = hit;
}
//生命力
private int live;
//法力
private int atk;
//攻擊力
private int hit;
public int getLive() {
return live;
}
public void setLive(int live) {
this.live = live;
}
public int getAtk() {
return atk;
}
public void setAtk(int atk) {
this.atk = atk;
}
public int getHit() {
return hit;
}
public void setHit(int hit) {
this.hit = hit;
}
}
public class Test {
public static void main(String[] args) {
RoleGame game=new RoleGame(1, 1, 1);
game.show();
RoleGameCareTaker careTaker=new RoleGameCareTaker();
careTaker.savePro("1",game.getRoleStateMemento());
game=new RoleGame(2, 2, 2);
careTaker.savePro("2", game.getRoleStateMemento());
game.show();
game=new RoleGame(3, 3, 3);
careTaker.savePro("3", game.getRoleStateMemento());
game.show();
game.setRoleStateMemento(careTaker.readPro("1"));
game.show();
game.setRoleStateMemento(careTaker.readPro("2"));
game.show();
}
}
結果圖
小結
1 將物件狀態的細節儲存在備忘錄中 哪天更改備忘錄也不至於影響到原物件。
2 適合功能比較複雜 又要儲存歷史屬性的具體類
3 就是追溯歷史變數的時候