Ho un metodo che dovrebbe restituire un'istantanea dello stato corrente e un altro metodo che ripristina quello stato.Restituisce un oggetto opaco al chiamante senza violare la sicurezza del tipo
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
La classe stato Snapshot
dovrebbe essere completamente opaca al chiamante - metodi né proprietà visibili - ma le sue proprietà devono essere visibili all'interno della classe MachineModel
. Potrei ovviamente farlo downcasting, ovvero avere CurrentSnapshot
restituire un object
e avere RestoreSnapshot
accettare un argomento object
che restituisce a Snapshot
.
Ma il casting forzato mi fa sentire sporco. Qual è il miglior design alternativo che mi consente di essere al sicuro e opaco?
Aggiornamento con la soluzione:
Finii per fare una combinazione della risposta accettata e la suggestione sulle interfacce. La classe Snapshot
è stata fatta una classe astratta pubblica, con un'implementazione privato all'interno 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);
}
}
Perché il costruttore e metodi di Snapshot
sono internal
, i chiamanti esterni alla assemblea lo vedono come un completamente opaco e non può ereditare da essa . I chiamanti all'interno dell'assemblea potrebbero chiamare Snapshot.Restore
anziché MachineModel.Restore
, ma non è un grosso problema. Inoltre, in pratica non è mai possibile implementare Snapshot.Restore
senza accesso ai membri privati di MachineModel
, che dovrebbero dissuadere le persone dal provare a farlo.
'MachineModel' avrà chiamanti sia dallo stesso gruppo che da gruppi esterni. –