2016-11-24 45 views
2

我很困惑這個紀念品應該如何實施。如何使用備忘錄設計模式保存多個對象的狀態?

我瞭解紀念品有一個。而備忘錄模式用於存儲不同的(以前)狀態,使人們可以在對象恢復到以前狀態

好讓說,我有多個對象,分別關於該來具有10個屬性,其中5個在每個個體對象的整個生命週期中保持不變,但其中5個屬性發生變化。所以我需要爲每個對象保存它以前的狀態並返回給它們。

問題:

我如何申請的備忘錄模式與這些對象?

我到目前爲止的想法:

所以備忘錄模式有3個班,備忘錄其中創建衆多,每一個狀態。 看守其中存儲對象的所有以前的狀態AKA 紀念品。然後創建創作者創建紀念品並且還從紀念品獲得狀態。

這意味着每個對象實例將需要它自己的看守實例(它的一個列表以前的狀態),這看守將有紀念品與此對象的5個屬性的先前狀態(而且當前狀態或僅以前的?),但所有對象接受看守政府可以使用相同的始發實例因爲發端可以用來創造新的紀念品到任何看守

這是如何執行還是誤解?

這將是這個樣子:

發起者和紀念品類

public class Memento { 
    private Object1Attributes state; 

    public Memento(Object1Attributes state){ 
     this.state = state; 
    } 

    public Object1Attributes getState(){ 
     return state; 
    }  
} 


static class Originator { 
    private Object1Attributes state; 

    public Memento saveStateToMemento(){ 
     return new Memento(state); 
    } 

    public void getStateFromMemento(Memento Memento){ 
     state = Memento.getState(); 
    } 

    public void setState(Object1Attributes state){ 
     this.state = state; 
    } 

    public Object1Attributes getState(){ 
     return state; 
    } 

} 

其他對象

public class Object1Attributes{ 
    string attribute1; 
    int attribute2; 
    someObject attribute3; 
    someObject attribute4; 
    someObject attribute5; 
} 

public class Object1 { 

    CareTaker careTaker = new CareTaker(); 

    Object1Attributes; 

    string attribute6; 
    int attribute7; 
    someObject attribute8; 
    someObject attribute9; 
    someObject attribute10; 


    public void returnToPreviousState(){ 
     if(caretaker.Length()>0){ 
      Object1Attributes = originator.getStateFromMemento(careTaker.get(caretaker.Length()-1)); 
      caretaker.remove(caretaker.Length()-1); 
     } 
    } 

    public void newState(ObjectAttributes OA){ 
     originator.setState(OA); 
     this.ObjectAttributes = OA; 
     this.caretaker.add(originator.saveStateToMemento()); 

    } 

} 

另一種選擇

將使得紀念品類和類發起人持有5個屬性,而不是封裝在另一個類中的5個屬性。像這樣:

public class Originator { 
    string attribute1; 
    int attribute2; 
    someObject attribute3; 
    someObject attribute4; 
    someObject attribute5; 

    public Memento saveStateToMemento(){ 
     return new Memento(attribute1, attribute2, attribute3, attribute4, attribute5); 
    } 

    public void setAttribute1(string state){ 
     this.attribute1 = state; 
    } 

    public void setAttribute2(int state){ 
     this.attribute2 = state; 
    } 

} 

這樣每個Object1實例將舉行,雖然其自身的鼻祖,而不是Object1Attributes的實例,併爲此發起方將包含在object1實例屬性的當前狀態;我不知道哪種方式是實施模式的正確方式。

所有在線的例子使用的紀念品來存儲一個「狀態」,這只是一個字符串,其中沒有涉及到可有多個狀態的多個對象的創建,所以這就是爲什麼我如此不確定。

回答

0

常見的陷阱的實施Memento模式被暴露始發的內部狀態時,一。這打破了稱爲封裝的基本OO概念之一。

的Memento的捕捉始發端的狀態的狀態。這可以是外部類型。您也可以在Memento中聲明所需的屬性。稍後,您可以使用中介者的狀態將原始發件人恢復到該狀態。

class Memento { 
    var state: State 
} 

始發方應有兩個備忘錄相關的方法:

class Originator { 
    func createMemento() -> Memento { 
     let currentState = State(...) 
     return Memento(state: currentState) 
    } 

    func apply(memento: Memento) { 
     let restoreState = memento.state 
     //...set the properties you want to restore from the memento state 
    } 
} 

最後,照顧者:

final class Caretaker { 
    private lazy var mementos = [String: Memento]() 

    func saveState(originator: Originator, identifier: String) { 
     let snapshot: GameWorldMemento = originator.createMemento() 
     snapshots[identifier] = snapshot 
    } 

    func restoreState(originator: Originator, identifier: String) { 
     if let snapshot = snapshots[identifier] { 
      originator.apply(memento: snapshot) 
     } 
    } 
} 

這是如何使用它:

let caretaker = CareTaker() 
let originator = Originator() 

// Save initial state 
caretaker.saveState(originator: originator, identifier: "save0") 

// modify the originator 
// ... 
// reset the originator to its original state 
caretaker.restoreState(originator: originator, identifier: "save0") 

這只是一個簡單的例子e來說明這個概念。

通常情況下,我會通過定義三種協議開始。 由於具體的「原創者」通常是已經存在的類型,我想補充一個類型擴展,以使其採取發起人協議。這樣我就不必修改它的代碼。實際上,這樣我可以在不修改原始代碼的情況下增強類型。

希望這會有所幫助。