Unveränderbare Ansichten veränderbarer Typen

7

Ich habe ein Projekt, bei dem ich eine ganze Menge Konfigurationsdaten erstellen muss, bevor ich einen Prozess ausführen kann. Während der Konfigurationsphase ist es sehr praktisch, die Daten als änderbar zu haben. Sobald die Konfiguration abgeschlossen ist, möchte ich jedoch eine unveränderliche Ansicht dieser Daten an den funktionalen Prozess übergeben, da dieser Prozess für viele seiner Berechnungen auf die Konfigurationsunveränderlichkeit angewiesen ist (z. B. die Möglichkeit, Dinge auf der Basis von Berechnungen vorab zu berechnen) Bei der anfänglichen Konfiguration.) Ich habe eine mögliche Lösung mit Hilfe von Schnittstellen gefunden, um eine schreibgeschützte Ansicht verfügbar zu machen, aber ich würde gerne wissen, ob jemand Probleme mit dieser Art von Ansatz gehabt hat oder ob es andere Empfehlungen dafür gibt löse dieses Problem.

Ein Beispiel für das Muster, das ich gerade verwende:

%Vor%

BEARBEITEN

Basierend auf den Eingaben von Mr. Lippert und cdhowie, habe ich folgendes zusammengestellt (einige Eigenschaften wurden entfernt, um zu vereinfachen):

%Vor%

FreezableList<T> ist, wie zu erwarten, eine Freezable-Implementierung von IList<T> . Dies bringt Vorteile bei der Isolierung, auf Kosten einer zusätzlichen Komplexität.

    
Dan Bryant 12.11.2010, 19:36
quelle

5 Antworten

13

Der Ansatz, den Sie beschreiben, funktioniert gut, wenn der "Client" (der Konsument der Schnittstelle) und der "Server" (der Anbieter der Klasse) eine gegenseitige Übereinstimmung haben, dass:

  • Der Client wird höflich sein und nicht versuchen, die Implementierungsdetails des Servers zu nutzen
  • Der Server wird höflich sein und das Objekt nicht mutieren, nachdem der Client einen Verweis darauf hat.

Wenn Sie zwischen den Leuten, die den Client schreiben, und den Leuten, die den Server schreiben, keine gute Arbeitsbeziehung haben, dann gehen die Dinge schnell in Birnenform. Ein unhöflicher Klient kann natürlich die Unveränderlichkeit wegwerfen, indem er auf den öffentlichen Konfigurationstyp überträgt. Ein unhöflicher Server kann eine unveränderliche Ansicht ausgeben und das Objekt dann mutieren, wenn der Client es am wenigsten erwartet.

Ein netter Ansatz besteht darin, zu verhindern, dass der Client den veränderbaren Typ jemals sieht:

%Vor%

Wenn Sie nun einen Frobber erstellen und mutieren wollen, können Sie einen Frobber.FrobBuilder erstellen. Wenn Sie Ihre Mutationen erledigt haben, rufen Sie Complete auf und erhalten eine schreibgeschützte Schnittstelle. (Und dann wird der Builder ungültig.) Da alle Mutationsimplementierungsdetails in einer privaten verschachtelten Klasse verborgen sind, können Sie die IReadOnly-Schnittstelle nicht zu RealFrobber "wegwerfen", sondern nur zu Frobber, der keine öffentlichen Methoden hat!

>

Auch kann der feindliche Client keinen eigenen Frobber erstellen, weil Frobber abstrakt ist und einen privaten Konstruktor hat. Die einzige Möglichkeit, einen Frobber zu machen, ist der Builder.

    
Eric Lippert 12.11.2010, 19:43
quelle
3

Dies funktioniert, aber "böswillige" Methoden versuchen möglicherweise, IConfiguration auf Configuration zu transformieren und damit die Beschränkungen zu umgehen, die durch die Schnittstelle verursacht werden. Wenn Sie sich darüber keine Sorgen machen, wird Ihr Ansatz gut funktionieren.

Normalerweise mache ich so etwas:

%Vor%

Alternativ könnten Sie Ihre veränderbaren Klassen in unveränderbare Klassen einbetten.

    
cdhowie 12.11.2010 19:40
quelle
2

Warum können Sie keine separate unveränderliche Ansicht des Objekts bereitstellen?

%Vor%

oder wenn Sie die zusätzliche Typisierung nicht mögen, machen Sie die Set-Mitglieder intern statt öffentlich - zugänglich innerhalb der Assembly, aber nicht von Clients davon?

    
plinth 12.11.2010 19:56
quelle
1

Ich arbeite regelmäßig mit einem großen, COM-basierten Framework (ArcGIS Engine von ESRI), das Änderungen in einigen Situationen sehr ähnlich behandelt: Es gibt die "default" IFoo -Schnittstellen für schreibgeschützten Zugriff und IFooEdit Schnittstellen (falls zutreffend) für Änderungen.

Dieser Rahmen ist ziemlich bekannt, und mir sind keine verbreiteten Beschwerden über diese bestimmte Designentscheidung bekannt.

Schließlich denke ich, dass es definitiv einen zusätzlichen Gedanken wert ist, zu entscheiden, welche "Perspektive" die Standardansicht wird: die schreibgeschützte Perspektive oder die Vollzugriffsansicht. Ich würde die schreibgeschützte Ansicht als Standard festlegen.

    
stakx 12.11.2010 19:54
quelle
0

Wie wäre es mit:

%Vor%

Ich habe es Readonly genannt, aber ich bin mir nicht sicher, ob das der beste Name dafür ist.

    
Jesper Larsen-Ledet 12.11.2010 19:50
quelle