2016-11-24 37 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来说明这个概念。

通常情况下,我会通过定义三种协议开始。 由于具体的“原创者”通常是已经存在的类型,我想补充一个类型扩展,以使其采取发起人协议。这样我就不必修改它的代码。实际上,这样我可以在不修改原始代码的情况下增强类型。

希望这会有所帮助。