我有一个方法应该返回当前状态的快照,另一个方法是恢复该状态.
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
Run Code Online (Sandbox Code Playgroud)
状态Snapshot类对调用者应该是完全不透明的 - 没有可见的方法或属性 - 但是它的属性必须在MachineModel类中可见.我显然可以通过向下转换来做到这一点,即CurrentSnapshot返回一个object,并RestoreSnapshot接受一个object它回归到一个参数Snapshot.
但这样的强迫铸造让我觉得很脏.什么是最好的替代设计,允许我既是类型安全的又是不透明的?
更新解决方案:
我结束了接受的答案和关于接口的建议.该Snapshot班是由一个公共抽象类,里面的私人执行MachineModel:
public class MachineModel
{
public abstract class Snapshot
{
protected internal Snapshot() {}
abstract internal void Restore(MachineModel model);
}
private class SnapshotImpl : Snapshot
{
/* etc */
}
public void Restore(Snapshot state)
{
state.Restore(this);
}
}
Run Code Online (Sandbox Code Playgroud)
因为构造函数和方法Snapshot是internal,程序集外部的调用者将其视为完全不透明且无法从中继承.程序集中的调用者可以调用Snapshot.Restore而不是MachineModel.Restore,但这不是一个大问题.此外,在实践中,如果Snapshot.Restore没有访问MachineModel私人成员,你就永远无法实施,这应该阻止人们尝试这样做.
您可以反转依赖关系并使 Snapshot 成为 MachineModel 的子级(嵌套类)。那么 Snapshot 只有一个公共(或内部)Restore()方法,该方法将 MachineModel 实例作为参数。由于 Snapshot 被定义为 MachineModel 的子级,因此它可以看到 MachineModel 的私有字段。
要恢复状态,您有以下示例中的两个选项。您可以调用 Snapshot.RestoreState(MachineModel) 或 MachineModel.Restore(Snapshot)*。
public class MachineModel
{
public class Snapshot
{
int _mmPrivateField;
public Snapshot(MachineModel mm)
{
// get mm's state
_mmPrivateField = mm._privateField;
}
public void RestoreState(MachineModel mm)
{
// restore mm's state
mm._privateField = _mmPrivateField;
}
}
int _privateField;
public Snapshot CurrentSnapshot
{
get { return new Snapshot(this); }
}
public void RestoreState(Snapshot ss)
{
ss.Restore(this);
}
}
Run Code Online (Sandbox Code Playgroud)
例子:
MachineModel mm1 = new MachineModel();
MachineModel.Snapshot ss = mm1.CurrentSnapshot;
MachineModel mm2 = new MachineModel();
mm2.RestoreState(ss);
Run Code Online (Sandbox Code Playgroud)
* 将 Snapshot.RestoreState() 设为并将所有调用者置于程序集之外会更简洁internal,因此执行恢复的唯一方法是通过 MachineModel.RestoreState()。但你在乔恩的回答中提到,同一程序集中会有调用者,所以没有太多意义。