Defensives kopieren von Effektiven Java
Lese ich "Effective Java" von Joshua Bloch, Artikel 39 defensive Kopie, und ich habe einige Fragen. Ich benutze immer das folgende Konstrukt:
MyObject.getSomeRef().setSomething(somevalue);
kurz für:
SomeRef s = MyClass.getSomeRef();
s.setSomething();
MyObject.setSomeRef(s);
Es immer funktioniert, aber ich denke, wenn meine getSomeRef()
wurde wieder eine Kopie dann meine Verknüpfung nicht mehr funktioniert, wie kann ich wissen, ob die Umsetzung der MyObject
ausgeblendet wird, wenn es sicher ist, verwenden Sie eine Verknüpfung oder nicht?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du bist gegen zwei Regeln der OO-Programmierung:
Beachten Sie, dass diese Regeln sind nur Regeln, und Sie kann oder sogar muss gebrochen werden, manchmal.
Aber wenn einige Daten im Besitz von einem Objekt, und das Objekt garantieren soll einige Invarianten, die auf die Objekte, die es besitzt, dann sollte es nicht verfügbar sein veränderlichen internen Datenstrukturen nach außen. Daher die Notwendigkeit für eine defensive Kopie.
Andere oft verwendete Redewendung ist zurück unveränderbar Blick auf die mutable Datenstrukturen:
Diesem idiom, oder das defensive kopieren idiom, können wichtig sein, zum Beispiel, wenn Sie müssen sicherstellen, dass jede änderung an der Liste geht durch das Objekt:
Wenn Sie nicht machen eine defensive Kopie oder Rückkehr eine unveränderliche Sicht auf die Liste, um einen Anrufer hinzufügen könnte, ein foo zu der Liste direkt ein, und der Hörer würde nicht aufgerufen werden.
addFoo()
Methode.Dokumentation ist die Art, wie Sie (sollten) wissen.
MyObject
sollte dokumentieren, ob die Dinge, die er macht, kann oder sollte verwendet werden, zu ändernMyObject
selbst. Sie sollten immer nur ein Objekt Bearbeiten, in der Art, ausdrücklich erteilt durch die Klasse.Zum Beispiel, hier sind die Javadocs für zwei Methoden in
List
man deren Ergebnis kann nicht verwendet werden, ändern Sie dieList
, und eine, deren Ergebnis ändern können, dieList
:toArray()
:subList()
:Ich würde sagen, dass die Stille aus der Dokumentation bedeutet, dass Sie sollten nicht es verwenden, um zu mutieren, das Objekt (verwenden Sie es nur für nur-lese-Zwecke).
Defensive Kopie ist eine gute Idee, aber Sie müssen verstehen, Wann und wo es auch genutzt wird. Wenn die web-Objekte, die Sie Bearbeiten, ist die interne, und es ist nicht beabsichtigt, thread-sichere, dann das defensive kopieren wird falsch angewendet.
Auf der anderen Seite, wenn dies web der Objekte, sind immer öffentlich verfügbar gemacht wird, dann sind Sie bei Gefahr der Verletzung Gesetz von Demeter. Wenn ja, prüfen, aussetzen einer manipulator-API auf Ihrem
myObject
.Nebenbei, dein code-Beispiel aus der
getSomeRef
Aussehen wie eine statische API. Ich würde vorschlagen, dass Sie eine statische API, gibt eine Kopie von einigen singleton entsprechend (z.B.copyOfSomething()
). Ähnlich wie bei einer statischen factory-Methode.call getSomeRef() zwei mal und vergleichen Sie es als Referenz, falls Sie unterschiedlich sind, dann ist die Rücksendung der Kopie aber es ist wieder das gleiche Beispiel.
Ich würde vorschlagen, die Definition einer
readableThing
- Schnittstelle oder Klasse, und es ableitenmutableThing
undimmutableThing
Schnittstellen. Eine Eigenschaft getter zurückgeben sollte eine dieser Schnittstellen basiert auf der Rücksendung der Bezug zu der Liste:Es ist schade, Java muss nicht grundsätzlich einen besseren job machen, der angibt, deklarativ wer ist "Eigentümer" verschiedene Objekte. Vor den Tagen der GC-frameworks, es war ärgerlich, dass, um zu verfolgen, wer im Besitz aller Objekte, ob Sie veränderlich oder nicht. Seit unveränderliche Objekte haben oft keine natürlichen Eigentümer, tracking Eigentum an unveränderliche Objekte war ein großer Aufwand. Generell ist jedoch jedes Objekt
Foo
mit Zustand, der können, mutiert sollte genau einen owner haben, was hinsichtlich der veränderlichen Aspekte derFoo
's Staat als Teile des eigenen Staates. Zum Beispiel, einArrayList
ist der Besitzer der ein array enthält die Elemente der Liste. Man ist unwahrscheinlich, dass zu schreiben, bug-free-Programme, die mit mutable-Objekte, wenn man nicht nachverfolgen, von wem Sie (oder zumindest Ihre veränderliche Aspekte).