2013-08-09 3 views
5
  1. Sollen defensive Kopien immer für Objektreferenzen von veränderbaren Objekten erstellt werden, die an Konstruktoren übergeben werden?Wie tief sollten Konstruktoren kopiert werden?

  2. Wenn ja, dann wie tief 'sollte ich gehen, um Kopien zu machen. Im folgenden Beispiel sollte ich tiefe Kopien in Kopierkonstruktoren aller beteiligten Klassen machen?

ZB:

class Graph { 
    AdjacencyList; 
    public Graph(Graph graph) { 
     this.list = graph.list; // shallow copy 
     OR 
     this.list = ArrayCopy(graph.list); // deep copy 
    } 
} 

class DFS implements GraphAlgo { 
    Graph g 
    DFS(Graph g) { 
    this.g = g; // shallow copy 
    OR 
    this.g = new Graph(graph) // deep copy 
    } 

    DFS(Algo algo) { 
    this.g = algo.g; // shallow copy 
    OR 
    this.g = new Graph(algo.g); // deep copy 
    } 

} 

class Algo { 
    GraphAlgo galgo 

    Algo (GraphAlgo dfsalgo) { 
     galgo = dfsalgo // shallow copy 
     OR 
     galgo = new DFSAlgo(dfsalgo); // deep copy 
    } 
} 

3 .. Was ist, wenn einige Klasse vergisst tiefe Kopie zu implementieren? Bedeutet das, dass ich niemals ein sicheres, tief kopiertes Objekt haben werde? Irgendeine Möglichkeit, dies zu verhindern?

+0

Wage es nicht, dies zu tun! Siehe http://StackOverflow.com/q/2156120/1065197 –

+1

Eine ObMention für "bevorzugen Unveränderlichkeit", dann müssen Sie sich nicht um solche Dinge kümmern. –

Antwort

5

Sollten Sie defensiv sein?
Nur wenn Sie es sein müssen.

Wie tief sollten Sie gehen?
So tief wie Sie brauchen.

Ton banal? Nun, die grundlegende Antwort auf diese Art von Fragen lautet: "Machen Sie so wenig wie nötig, um die erforderliche Funktionalität zu liefern".

2

Allgemein: Erstellen Sie keine defensiven Kopien, es sei denn, Sie vertrauen dem aufrufenden Code nicht.

Do: Dokumentieren Sie die Schnittstelle und sagen Sie, dass sie nichts ändern dürfen, wenn sie ein Problem verursachen.

Manchmal: Stellen Sie zwei Konstruktoren zur Verfügung. Man benutzt das Objekt. Man macht eine Kopie. Lassen Sie dann den Anrufer denjenigen anrufen, der bei Bedarf eine Kopie erstellt. Der Aufrufer kann alle Referenzen auf dieses Objekt sofort nach dem Aufruf des Konstruktors verwerfen. In diesem Fall wird keine Kopie benötigt.

Algo (GraphAlgo dfsalgo, boolean doCopy) { 
    if (doCopy) { 
     galgo = new DFSAlgo(dfsalgo); // deep copy 
    } else { 
     galgo = dfsalgo // shallow copy 
    } 
} 

Wenn Sie die Telefonvorwahl vertrauen: das Problem ignorieren. Erwarte, dass es Kopien von allem erstellt, was es nicht verwerfen wird (von seinem eigenen Standpunkt aus), bevor es deinen Code aufruft.

Paranoia bedeutet nicht, dass sie nicht raus sind, um dich zu bekommen. Aber das bedeutet nicht, dass sie es auch sind.