Wie man eine unveränderbare Wertklasse mit java.lang.String erstellt?

8

Ziel

Erstellen Sie eine Klasse, die als unveränderliche Liste von String Objekte.

Annäherung

Ich habe beschlossen, Google Guava ImmutableList & lt; E & gt; Sammlung, anstatt ein einfaches Liste & lt; E & gt; mit Liste & lt; E & gt; , die nicht gewappnet ist, umgebrochen zu werden (Quelle: Unveränderliche Sammlungen erklärt ).

Anforderungen

  • Klasse mit einem "Werthalter", der über Threads verwendet werden kann
  • Kein Code darf die inneren Werte nach der Erstellung ändern

Nice-to-haves

Versuche

Hier einige Versuche, obwohl mehr Kombinationen möglich sind. Verzeihen Sie die humorvolle Wiedergabe.

Versuch Nr. 1 (einschließlich Verwendungsbeispiel)

%Vor%

Versuch # 2

%Vor%

Versuch # 3

%Vor%

Zusammenfassung der Unterschiede

  • 1 behält List & lt; E & gt; in den öffentlichen Schnittstellen, wobei die Unveränderlichkeit im JavaDoc dokumentiert wird.

  • 2 speichert und stellt alles als Google dar Guava ImmutableList & lt; E & gt;

  • 3 behält die interne Referenz als endgültig auf Kosten der Erstellung eines spezialisierten Konstruktors, wodurch die Initialisierung der statischen Factory-Methode in Ermangelung anderer Initialisierungsoptionen (die tatsächlich in der realen Klasse vorhanden sind) möglicherweise albern aussieht.

Frage

Bitte helfen Sie mir, unter einer dieser Implementierungen zu wählen, mit Ihrer Begründung für die Wahl.

Ich denke, der Hauptnachteil von Ansatz Nr. 2 besteht darin, dass Kunden den speziellen Google Guava Typ und wahrscheinlich sollten sie nicht?

    
Robottinosino 18.09.2012, 09:12
quelle

3 Antworten

3

Klar, # 3 ist meiner Meinung nach die beste Wahl. final erzwingt und dokumentiert die Unveränderbarkeit von (diesem Feld) der Klasse, nicht nur die Tatsache, dass List selbst unveränderlich ist.

Ob Sie ein List mit einem Javadoc oder einem tatsächlichen ImmutableList im Getter angeben, ist eine andere Sache. Ich habe Meinungen gesehen, dass das Zurückgeben von ImmutableList eindeutig die Absicht dokumentiert, aber trotzdem binden Sie sich dann an eine Implementierung anstelle einer Schnittstelle für etwas, das niedrig ist und in Zukunft geändert werden müsste (selbst wenn Unveränderbarkeit ist) "allgemein" gut). Es ist also eher eine globale Design-Wahl für Ihre Anwendung als nur für einen Anwendungsfall. Wenn Sie ImmutableList verwenden, denke ich nicht, dass dies ein echtes Problem für die Clients ist. Der Name ist eindeutig und kann über Ihre IDE leicht als eine Implementierung von List gesehen werden, und sie können auf das Javadoc if zugreifen sie wollen mehr Informationen. Und wer weiß, vielleicht mögen sie es und fangen an, es auch zu benutzen, mit all den anderen Leckereien, die Guava bietet: -)

    
Frank Pavageau 18.09.2012, 09:52
quelle
1

Aus Ihrer Problemstellung ("es sollte nur eine Klasse für eine gegebene Menge von Strings geben"), klingt es wie das, was Sie wirklich wollen, ist ein Interner<ImmutableSet<String>> .

  • Interner ist ein Dienstprogramm (konstruiere eins mit Interners.newStrongInterner() ), um sicherzustellen, dass Sie nur eine Instanz eines Objekts mit beliebigen Daten haben.
  • ImmutableSet ist die richtige Wahl, wenn Ihre Sammlung unveränderlich ist und eine Sammlung in beliebiger Reihenfolge, die den Test der Mitgliedschaft unterstützt.

Alternativ können Sie sich auch ein Cache<ImmutableSet<String>> ansehen (siehe Erläuterung zu Caches ) Details).

    
Daniel Pryden 18.09.2012 21:34
quelle
0

Ich würde Attempt #2 über Attempt #1 verwenden, weil es dokumentiert, dass Sie ImmutableList-Instanzen immer zurückgeben. Generell ist es sinnvoll Rückgabetypen so spezifisch wie möglich und Parametertypen so allgemein wie möglich zu wählen. Aber für beide Fälle bevorzugen Schnittstellen gegenüber konkreten Klassen.

Nun, ImmutableList ist eine abstrakte Klasse und keine Schnittstelle. Aber aufgrund seiner Natur verhält es sich sehr ähnlich wie eine Schnittstelle.

Attempt #3 ist sinnvoll, wenn Ihr Klassenmitgliedsreferenz spellings sich nicht für die Lebensdauer des Objekts ändern kann und / oder Sie die gesamte Klasse selbst unveränderbar machen möchten. Andernfalls, wenn spellings während der Lebensdauer des Objekts einer anderen ImmutableList zugewiesen werden kann, ist dies nicht sinnvoll.

Angesichts des Anwendungsfalls in Ihrem Beispiel neige ich dazu zu sagen, dass # 3 die beste Wahl ist.

    
Fabian Barney 18.09.2012 09:50
quelle

Tags und Links