【发布时间】:2018-02-02 15:42:18
【问题描述】:
我目前正在尝试在 Kotlin 中实现一些设计模式作为练习,但我有点坚持使用“Memento”模式。我的参考资源是SourceMaking: Memento。
我要实现这个结构:
在遵循他们的“清单”时
- 确定“看守人”和“发起人”的角色。
- 创建一个 Memento 类并将创建者声明为朋友。
- 管理员知道何时“检查”发起人。
- 创建者创建一个备忘录并将其状态复制到该备忘录。
- 看守握着(但无法窥视)纪念品。
- 管理员知道何时“回滚”发起者。
- 创建者使用 Memento 中保存的状态恢复自身。
我无法执行第 5 步。如何创建一个 Memento 对象,其字段可以从 Originator 实例内部读取,但对 Caretaker 完全不透明?
我已经在 Java 中成功实现了如下:
public class Originator {
private final int id;
private String title;
private String description;
public Originator(int id) {
this.id = id;
}
/* skipping title and description getter & setter */
public Memento saveState() {
return new Memento(new State(id, title, description));
}
public void restore(Memento memento) {
id = memento.state.id;
title = memento.state.title;
description = memento.state.description;
}
private class State {
private final int id;
private final String title;
private final String description;
public State(int id, String title, String description) {
this.id = id;
this.title = title;
this.description = description;
}
}
public class Memento {
private final State state;
public Memento(State state) {
this.state = state;
}
}
}
还有一个看护人
public class Caretaker {
public Originator originator;
public Caretaker(@NotNull Originator originator) {
this.originator = originator;
}
public Originator.Memento save() {
return originator.saveState();
}
public void restore(@NotNull Originator.Memento memento) {
originator.restoreFromState(memento);
}
}
因为它们是内部类,我可以从我的Originator 实例中读取Memento 和State 的私有字段,但是对于Caretaker 我的Memento 实例是完全不透明的(仅显示Objects成员函数)。
现在我该如何在 Kotlin 中实现这种精确的行为?基本上我错过了读取内部类私有字段的功能。
我能想到的最接近的事情是这样的:
class Originator(id: Long) {
private var id: Long = id
var description: String = ""
var title: String = ""
fun saveState() = Memento(State(id, title, description))
fun restoreState(memento: Memento) {
id = memento.state.id // <-- cannot access 'state': it is private in 'Memento'
title = memento.state.title // <-- cannot access 'state': it is private in 'Memento'
description = memento.state.description // <-- cannot access 'state': it is private in 'Memento'
}
inner class State(private val id: Long,
private val title: String,
private val description: String)
inner class Memento(private val state: State)
}
这具有Memento 对我的Caretaker 实例完全不透明的预期效果,但我也无法从Originator 中读取字段。
顺便说一句,这段代码几乎与应用到我的 Java 代码的 IntelliJ 的“将 Java 转换为 Kotlin”功能生成的代码完全相同(而且它显然也不能编译)。
那么我在这里遗漏了什么明显(或神奇)的东西吗?也许不是类图中显示的结构?或者这些确切的规范不能在 Kotlin 中实现?
另一方面:Memento 对象的不透明性要求实际上是 Memento 模式的通俗接受的属性,还是 SourceMaking 提出了这个要求?
【问题讨论】:
标签: java design-patterns kotlin memento