我对备忘录应该如何实现感到非常困惑。
我知道Memento有一个State。Memento模式用于存储不同的(先前的)状态,以便可以将对象还原到以前的状态,
假设我有多个对象,每个属性都有10个属性,其中5个属性在每个对象的整个生命周期中保持不变,但其中5个属性会发生变化。因此,对于每个对象,我需要保存它以前的状态并返回到它们。
问题:
如何将Memento模式应用于这些对象?
到目前为止我的想法::
因此,Memento模式有3个类,Memento,您创建了许多类,每个状态都有一个。,它存储AKA 纪念品的所有以前的状态。然后是发起人,它创建Mementos,并从Memento获取状态。
这意味着每个对象实例都需要它自己的看管器实例(它以前状态的列表),并且这个看门人将使用 mementos ,其中包含该对象的5个属性的先前状态(以及当前状态还是仅是以前的状态?),但是所有具有托管器的对象都可以使用相同的原始实例E 249,因为E 150发起人E 251可以用于在任何E 152看护器E 253中创建新的mementos。
这是如何实施的,还是我误解了?
看起来会是这样的:
发起人和Memento类
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());
}
}
另一种选择
将使Memento类和发起人类保存这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实例中属性的当前状态;我不知道实现模式的正确方式是哪种方式。
所有在线示例都使用mementos存储一个"state“,它只是一个字符串,它们中没有一个涉及创建可以具有多个状态的多个对象,这就是为什么我如此不确定的原因。
发布于 2017-11-09 14:03:33
实现Memento模式时常见的缺陷之一是公开发起人的内部状态。这打破了一个被称为封装的基本的面向对象概念。
Memento有一个捕获发起人状态的状态。这可以是外部类型。您还可以在Memento本身中声明所需的属性。稍后,您可以使用Mediator的状态将发起人还原回该状态。
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")这只是一个简单的例子来说明这个概念。
通常情况下,我会从定义这三个协议开始。由于具体的“发起人”通常已经存在类型,所以我会添加一个类型扩展来使它采用发起人协议。这样我就不用修改它的代码了。实际上,这样我就可以在不修改原始代码的情况下增强类型。
希望这能有所帮助。
https://stackoverflow.com/questions/40795754
复制相似问题