У меня есть метод, который должен возвращать снимок текущего состояния, и другой метод, который восстанавливает это состояние.
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
Класс состояния 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);
}
}
Поскольку конструктор и методы Snapshot
равны internal
, вызывающие извне сборки видят его как полностью непрозрачный и не могут наследовать от него. Вызывающие в сборке могут звонить Snapshot.Restore
, а не MachineModel.Restore
, но это не большая проблема. Более того, на практике вы никогда не сможете внедрить Snapshot.Restore
без доступа к частным членам MachineModel
, что должно отговорить людей от попыток сделать это.