gpt4 book ai didi

design-patterns - 如何使用 memento 设计模式保存多个对象的状态?

转载 作者:行者123 更新时间:2023-12-04 07:19:52 25 4
gpt4 key购买 nike

我对纪念品应该如何实现感到非常困惑。

我了解 纪念品 有一个 状态 .和 纪念品图案用于存储不同的(以前的)状态 以便可以恢复 对象 上一个 状态 ,

好吧,假设我有多个 对象 ,每个都有 10 个属性,其中 5 个在每个人的一生中保持不变对象 , 但其中有 5 个发生了变化。所以我需要,对于每个 对象 保存它以前的状态并返回到它们。

问题:

How do I apply the Memento Pattern with these objects?



到目前为止我的想法:

所以 纪念品图案有 3 个类(class), 纪念品 您创建了许多,每个州一个。 看守 它存储对象 AKA 的所有先前状态纪念品 .然后是 发起人 创建 纪念品 并且还从 获取状态纪念品 .

这意味着每个 对象实例 需要它自己的 看守实例 (它以前的状态列表),还有这个 看守 会有 纪念品 具有此对象的 5 个属性的先前状态(以及当前状态还是仅先前的状态?),但所有具有看守者的对象都可以使用相同的 发起者实例 因为 发起人 可用于在任何 中创建新的纪念品看守 .

这是如何实现还是我误解了它?

它看起来像这样:

Originator and Memento class


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;
}

}

Other object


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());

}

}

Another option



将使 Memento 类和 Originator 类拥有 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 实例都将拥有自己的 Originator 实例而不是 Object1Attributes,并且此 Originator 将包含 object1 实例中属性的当前状态;我不知道哪种方式是实现模式的正确方式。

所有在线示例都使用 mementos 来存储只是一个字符串的“状态”,它们都不涉及创建可以具有多个状态的多个对象,所以这就是我如此不确定的原因。

最佳答案

实现 Memento 模式时的常见陷阱之一是暴露 Originator 的内部状态。这打破了称为封装的基本 OO 概念之一。

Memento 具有捕获 Originator 状态的状态。这可以是外部类型。您还可以在 Memento 本身中声明所需的属性。稍后您可以使用 Mediator 的状态将 Originator 恢复到该状态。

class Memento {
var state: State
}

Originator 应具有两种与 Memento 相关的方法:
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")

这只是一个简化的例子来说明这个概念。

通常,我会从定义三个协议(protocol)开始。 由于具体的“发起者”通常已经存在类型,我会添加一个类型扩展以使其采用 Originator 协议(protocol)。 这样我就不必修改它的代码了。实际上,这样我可以在不修改其原始代码的情况下增强类型。

希望这可以帮助。

关于design-patterns - 如何使用 memento 设计模式保存多个对象的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40795754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com