Sollen defensive Kopien IMMER gemacht werden?

8

Ich habe einen Code, der ein zweiteiliges Diagramm als Eingabe verwendet und eine Map mit dem Schlüssel "1" mit einem Wert zurückgibt, der eine Liste von "Knoten in Set1" und Schlüssel "2" ist, dessen Wert eine Liste von "Knoten in Set2 ist ". Jetzt ist die Karte veränderbar. Theoretisch sollte ich eine defensive Kopie für die Rückgabe einer Karte verwenden. Aber ist es in diesem Fall wirklich erforderlich? Es scheint ein Overkill.

ex:

%Vor%     
JavaDeveloper 09.08.2013, 06:33
quelle

6 Antworten

6

Kommt drauf an:)

  • Sie können Ihre Klasse entsprechend dokumentieren, indem Sie angeben, dass die zurückgegebene Map eine veränderbare direkte Ansicht des veränderbaren Status des BiPartite-Objekts ist. Ich würde das aber nicht empfehlen.
  • Sie können die interne Map mit Collections.unmodifiableMap(map) in getMap() und dokumentieren, dass sie den veränderbaren Status des BiPartite-Objekts widerspiegelt. Dies kann ein gültiger Ansatz sein, solange das BiPartite-Objekt nicht threadsicher sein soll. Wenn der Kunde die zurückgegebene Map als stabilen Snapshot behalten möchte, kann er sie selbst kopieren. Wenn das nicht benötigt wird, kann sie von dem schnellen Verpackungsvorgang profitieren.
  • Sie können immer eine vollständige Kopie zurückgeben. Das wäre am sinnvollsten, wenn Sie das BiPartite-Objekt tatsächlich threadsafe machen. In diesem Fall müssen Sie auch alle Operationen der internen Karte synchronisieren (einschließlich der Kartenkopieroperation!).

Grundsätzlich läuft es auf Folgendes hinaus: Denken Sie darüber nach, wie die BiPartite-Klasse und ihre Methoden verwendet werden sollen, wählen Sie eine geeignete Implementierung dafür und dokumentieren Sie deutlich sowohl das Verhalten der Klasse als auch die dahinter stehenden Gründe.

    
creinig 09.08.2013, 06:49
quelle
5

Ja, Sie sollten eine defensive Kopie zurückgeben. Wenn Sie Bedenken hinsichtlich der Ressourcennutzung haben, können Sie eine Karte zurückgeben, die eine nicht änderbare Ansicht Ihrer privaten Karte darstellt:

%Vor%     
Joni 09.08.2013 06:42
quelle
2

Das Wort "IMMER" ist selten richtig, wenn man Muster und gute Programmierpraktiken erklärt. Alles hängt vom Kontext ab.

In Ihrem Fall sind die Methode BiPartite#getMap und die Klasse selbst "Paket privat", so dass Clients (Benutzer Ihres Codes) nicht in der Lage sind, sie direkt zu verwenden. Wenn Sie wissen, dass Sie diese Karte niemals außerhalb der Grenzen dieses Pakets speichern oder zurückgeben, ist es ziemlich sicher, dass Sie keine Abwehrkopie erstellen müssen.

    
cherouvim 09.08.2013 06:46
quelle
1

Das hängt von den Konventionen Ihres Codes ab. Ich folge einer Konvention, alles zu kopieren, was du behalten willst. es ist die Verantwortung des Anrufers.

Dies ist effizienter, aber nicht robust, wenn Sie nicht wissen, dass der Aufrufer dieser Konvention folgt.

    
Peter Lawrey 09.08.2013 06:40
quelle
1

Ja, du solltest, Denn sonst kann der Client das private Feld der Klasse ändern, wodurch sich die Klasse falsch verhält.

    
Salih Erikci 09.08.2013 06:38
quelle
0

Defensive Kopien sind eine schlechte Sache imho, weil die meisten Java-Frameworks, auf die ich gestoßen bin, erwarten, dass ein Getter immer den gleichen Wert zurückgibt und das schnell macht.

Wenn Sie sich vor fehlerhaften Clients Ihres Codes schützen möchten, sollten Sie nur die Methode calcBipartite () verfügbar machen und eine neu berechnete Map zurückgeben lassen. Der Client, der die Methode verwendet, muss entscheiden, wie das erstellte Objekt verwendet wird und wie oft calcBipartite () aufgerufen wird.

Wenn Sie der einzige Client Ihres Codes sind, sollten Sie weder kopieren noch umbrechen.

    
TomWolk 09.08.2013 07:37
quelle

Tags und Links