Wie wird eine Sammlung aus einem Parameter bevorzugt?

8

Ich habe diese Klasse:

%Vor%

Das ist offensichtlich ein schlechter Stil, weil ich einen gemeinsamen veränderbaren Zustand einführe. Was ist der bevorzugte Weg, um damit umzugehen?

  • Ignoriere es?
  • Klonen Sie die Sammlung?
  • ...?

BEARBEITEN: Um zu verdeutlichen, warum das schlecht ist, stell dir folgendes vor:

%Vor%

Wenn Sie nur die Referenz speichern, können Sie Daten in das private Feld myObject.data injizieren, obwohl es vollständig privat sein sollte.

Abhängig von der Art von MyClass könnte dies schwerwiegende Auswirkungen haben.

    
Daniel Rikowski 03.03.2010, 08:26
quelle

5 Antworten

9

Der beste Weg ist, den Parameter tief zu klonen. Aus Leistungsgründen ist dies in der Regel nicht möglich. Darüber hinaus können nicht alle Objekte geklont werden, so dass tiefes Kopieren Ausnahmen auslösen kann und alle Arten von Kopfschmerzen verursachen kann.

Der nächstbeste Weg wäre ein "Copy-on-Write" -Klon. In der Java-Laufzeitumgebung wird dies nicht unterstützt.

Wenn Sie glauben, dass jemand die Sammlung mutieren kann, führen Sie eine flache Kopie mit dem Kopierkonstruktor aus:

%Vor%

Dies wird Ihr Problem lösen (da String unveränderlich ist), aber es wird fehlschlagen, wenn der Typ in der Menge veränderbar ist.

Eine andere Lösung besteht darin, die Sets immer unveränderlich zu machen, sobald Sie sie irgendwo speichern:

%Vor%

Die Idee ist, Sammlungen so schnell wie möglich in "Wertobjekte" umzuwandeln. Jeder, der die Sammlung ändern möchte, muss sie kopieren, ändern und dann speichern.

Innerhalb einer Klasse können Sie das Set veränderbar halten und es in den Getter einbinden (was Sie ohnehin tun sollten).

Probleme mit diesem Ansatz: Leistung (aber es ist wahrscheinlich nicht so schlimm, wie Sie erwarten würden) und Disziplin (bricht, wenn Sie es irgendwo vergessen).

    
Aaron Digulla 03.03.2010, 08:48
quelle
3
  • Null-Überprüfung (wenn Sie null einschränken möchten)
  • Entweder eine defensive Kopie (wenn Sie keinen gemeinsamen Status haben wollen)
  • oder wie Sie es taten (wenn eine Live-Ansicht von Daten nützlich ist)

Hängt stark von Ihren Anforderungen ab.

Bearbeitet: Ignorieren sollte keine Option sein. Silent Fail ist, naja ... ein Albtraum für das Debugging.

    
whiskeysierra 03.03.2010 08:37
quelle
1
%Vor%     
Paul McKenzie 03.03.2010 08:59
quelle
1

Entschuldigen Sie, dass ich Ihre Bedenken nicht direkt angesprochen habe, aber ich würde niemals eine Sammlung direkt an eine setXxx () - Bean-Setter-Methode übergeben. Stattdessen würde ich tun:

%Vor%

Ich würde mich für defensives Kopieren / Deep Cloning nur dann entscheiden, wenn ich sicher bin, dass es keine Nebenwirkungen bei der Verwendung geben würde, und was die Geschwindigkeit angeht, würde ich mich nicht damit beschäftigen, da die Zuverlässigkeit von Business-Anwendungen 10 Mal beträgt mehr Priorität als Geschwindigkeit. ; -)

    
dimitarvp 03.03.2010 10:08
quelle
0

Eine Idee wird sein, die Daten als String-Array zu übergeben und das Set in MyClass zu erstellen. Natürlich sollte MyClass testen, dass die Eingabedaten gültig sind. Ich glaube, dass dies ohnehin eine gute Praxis ist.

Wenn sowohl der Aufrufer von MyClass als auch MyClass selbst mit einem Set<String> arbeiten, könnten Sie das Klonen der Sammlung in Betracht ziehen. Das Set muss jedoch irgendwie konstruiert werden. Ich würde es vorziehen, diese Verantwortung auf MyClass zu verschieben.

    
kgiannakakis 03.03.2010 08:36
quelle

Tags und Links