我有一个方法应该返回当前状态的快照,另一个方法是恢复该状态.
- public class MachineModel
- {
- public Snapshot CurrentSnapshot { get; }
- public void RestoreSnapshot (Snapshot saved) { /* etc */ };
- }
状态Snapshot类对调用者应该是完全不透明的 – 没有可见的方法或属性 – 但是它的属性必须在MachineModel类中可见.我显然可以通过向下转换来实现这一点,即让CurrentSnapshot返回一个对象,并让RestoreSnapshot接受一个对象参数,它将其转换回快照.
但这样的强迫铸造让我觉得很脏.什么是最好的替代设计,允许我既是类型安全的又是不透明的?
更新解决方案:
我结束了接受的答案和关于接口的建议. 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);
- }
- }
由于Snapshot的构造函数和方法是内部的,因此程序集外部的调用者将其视为完全不透明且无法从中继承.程序集中的调用者可以调用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);
- }
- }
例:
- MachineModel mm1 = new MachineModel();
- MachineModel.Snapshot ss = mm1.CurrentSnapshot;
- MachineModel mm2 = new MachineModel();
- mm2.RestoreState(ss);
*将Snapshot.RestoreState()作为内部并将所有调用者放在程序集之外是最简洁的,因此执行还原的唯一方法是通过MachineModel.RestoreState().但是你在Jon的回答中提到在同一个程序集中会有调用者,所以没有多大意义.