Übergeben des gesamten Objekts vs. Übergeben der Eigenschaft des Objekts
Lesezeit: 7 Minuten
Lukas
Ich denke über die Lösung für meine Anwendung nach. Hier ist die Situation: Ich habe eine Klasse mit einer Methode, die ObjectA als Eingabeparameter nimmt und mehrere kleine Methoden aufruft. Jede dieser Methoden benötigt einige Teile von ObjectA (sie überlappen sich nicht, dh method1() braucht ObjectA.field1 Und ObjectA.field2, method2() braucht ObjectA.field3 usw…)
Ist es angesichts der allgemeinen guten Codepraktiken und der Leistung besser, ObjectA an jede dieser Methoden zu übergeben, damit sie den benötigten Wert selbst extrahieren können, oder ist es besser, ihnen einfach Werte zu übergeben? Ich meine:
Ich denke, die erste Option ist besser. Die äußere Welt muss nicht wissen, was Ihre Funktion intern mit dem Objekt macht (dh auf welche Felder sie zugreift.)
– TheLostMind
15. Januar 2014 um 11:30 Uhr
Es richtet sich ganz nach Ihren Bedürfnissen. Wenn Sie nicht möchten, dass die andere Methode die Felder Ihres Objekts ändert, übergeben Sie die Objektreferenz nicht. Übergeben Sie einfach die erforderlichen Werte. Wenn nicht, dann ist es besser, die Objektreferenz zu übergeben und die Werte davon nach Bedarf zu verwenden, anstatt so viele Parameter im Methodenaufruf hinzuzufügen.
– Raul
15. Januar 2014 um 11:31 Uhr
Es hat sich bewährt, den Code so einfach verständlich und klar wie möglich zu gestalten. In diesem Fall vermute ich, dass es keinen Leistungsunterschied gibt oder er zu gering ist, um ihn zu messen.
– Peter Lawrey
15. Januar 2014 um 11:37 Uhr
Christoph
Denken Sie daran, dass Sie mit Ihrem Code nicht wirklich bestehen ObjectA. Sie übergeben nämlich den Referenztyp an ObjectAalso auf einer Leistungsnote den Unterschied zwischen dem Bestehen von a String Objektreferenz und a ObjectA Objektreferenz wäre vernachlässigbar.
So wie ich es schreiben würde
Ich würde das gesamte Objekt übergeben, wenn die Methode für die Klasse relevant ist. Meine Begründung dafür ist, das Klassenwissen so weit wie möglich aufzuteilen. Was ich damit meine ist folgendes.
public void doSomethingRelatedToTheClass(String param)
{
// Do something with param.
}
Meine erste Kritik hier ist, dass diese Methode davon ausgeht, dass die Eingabe das richtige Feld ist. Meine zweite ist, dass die Klasse, die diesen Code aufruft, jetzt ein bisschen mehr über diese Methode wissen muss, weil sie sie so aufrufen muss:
Und das bedeutet, wenn Sie das bei einem anderen Mitglied finden ObjectA funktioniert innerhalb dieser Methode besser, oder Sie möchten auf andere Mitglieder von zugreifen ObjectAund du veränderst dich doSomething() Um diese Änderung widerzuspiegeln, müssen Sie auch den Methodenaufruf ändern in:
Indem Sie also das gesamte Objekt übergeben, abstrahieren Sie dieses Detail, und die Methode kann damit umgehen. nämlich:
doSomethingRelatedToTheClass(myObject); // Doesn't need to know what you do with it.
public void doSomethingRelatedToTheClass(ObjectA object)
{
String val = object.getValue();
String otherVal = object.getOtherValue();
}
Wenn eine Änderung an einer Klasse zu einer Änderung an anderen Klassen führt, wird dies ein Anti-Pattern genannt Schrotflinten-Chirurgie.
Bearbeiten
Ich hatte Gelegenheit, meine Antwort hier zu überprüfen, und ich habe meine ursprüngliche Antwort leicht geändert, weil ich glaube, dass dies nicht die beste Lösung für ist alle Situationen. Wenn sich eine Methode wie oben speziell auf eine Klasse bezieht, dann wird die Instanziierung dieser Klasse (oder bevorzugter ihrer Oberklasse oder implementierten Schnittstelle[s]) sollte der Parameter sein.
Wenn dies nicht der Fall ist, kann die Funktionalität generisch sein. Ein Beispiel für eine generische Funktion könnte sein:
public String[] findNouns(String sentence);
In diesem Fall kann das Auffinden der Substantive in einem Satz für viele Anwendungsfälle geeignet sein und nicht nur für die Anwendungsfälle, die Sie definiert haben. Daher ist das Übergeben des Werts der einzig sinnvolle Ansatz, da Sie sonst zwei logische Teile miteinander verbinden, die keine direkte Beziehung haben. Das Finden von Substantiven und dem beliebigen Objekt, das Sie definiert haben.
In Summe
Wenn die Methode Logik ist, die sich auf das Objekt bezieht, übergeben Sie das Objekt
Wenn die Methode nichts mit dem Objekt zu tun hat und das Objekt sie nur als Hilfsfunktion verwendet, übergeben Sie den Wert und benennen Sie die Funktion generisch.
Ein Problem, das dabei entstehen kann, ist das Durchlaufen des Ganzen ObjectA Gemäß der Funktionsdefinition muss jede Testfunktion, die die API aufruft, eine Fälschung instanziieren ObjectA mit allen Feldern, auch wenn die Funktion nur eine Teilmenge dieser Felder verwendet. Wenn Sie dann ein Feld auf der hinzufügen ObjectA -Klasse müssen Sie all diese gefälschten Objekte ändern, auch wenn sich die Implementierung nicht wirklich geändert hat. Dies kann durch die Verwendung von Factories für Stubs vermieden werden, erfordert aber noch mehr Code.
– Luca Molteni
7. März 2016 um 9:29 Uhr
Eine andere Sache ist, dass ich in meinem aktuellen Projekt viel Legacy-Code sehe, der zu viele Daten übergibt. Wenn eine Eigenschaft benötigt wird und Sie ein ganzes Objekt übergeben, nur für den Fall, dass Sie eines Tages eine andere Eigenschaft benötigen … YAGNI
– Kiedysktos
5. Januar 2018 um 10:11 Uhr
Nun, macht diese Funktion (von der ich annehme, dass sie außerhalb der Klasse lebt) etwas ausschließlich für diese Klasse? Oder ist es eine generische Funktionalität? Könnte es generische Funktionalität sein?
– Christoph
5. Januar 2018 um 13:15 Uhr
Eine andere Option, die ich als Verbesserung der Objektreferenz empfinde, besteht darin, einen Typ dafür zu erstellen, z. B. ein einfaches Wertobjekt mit nur den Attributen, die Sie benötigen. Dann weiß die Funktion gerade genug und ist nicht mehr vom Hauptobjekt abhängig.
– Damian Roche
1. August 2022 um 10:56 Uhr
n4rzul
Lassen Sie uns ein Szenario untersuchen. Nun, dies kann Ihr Szenario sein oder auch nicht, aber es veranschaulicht einen Punkt.
Nehmen wir an, field1 und field2 sind in Ihrem Fall zwei ganze Zahlen und method1 summiert sie und gibt das Ergebnis zurück.
Wenn Sie die Objekte übergeben, kann diese Methode immer nur diese beiden Felder summieren. Die Methode ist nun auch stark mit diesen Objekten gekoppelt.
Übergeben Sie dagegen nur die Felder, die beiden Integer, wird Ihre Methode in diesem Fall generischer. Sie können jetzt 2 beliebige ganze Zahlen summieren, unabhängig davon, auf welchen Objekten sie sich befinden.
Im Allgemeinen sollten Sie jedoch immer so wenig Ihrer Objekte anderen Methoden und Klassen aussetzen. Dies fördert eine lose Kopplung.
Ausnahmen
AS maaartinus weist darauf hin, wenn zum Beispiel field1 und field2 Points wären und method1 den Abstand zwischen diesen beiden Punkten berechnet, dann müsste ich zustimmen, dass das Übergeben von zwei Points besser wäre als das Übergeben von 2 xy Integer-Paaren (4 Parameter).
Hoffe das hilft
Ich würde sagen, es kommt darauf an. Eine Methode kann klarer und allgemeiner sein, wenn sie auf den Argumenten operiert, anstatt ein ganzes Objekt zu benötigen. Manchmal haben Sie die Argumente parat (z. x Und y) und müssten diese erst zu zB a aggregieren Point um die Methode aufrufen zu können. Manchmal haben Sie ein anderes, nicht verwandtes Objekt (zB einige ImmutablePointoffensichtlich nicht verlängern java.awt.Point) und müsste die Koordinaten extrahieren und ein zu übergebendes Objekt erstellen.
Wenn das übergebene Objekt die richtige Abstraktion ist, ist es normalerweise der richtige Weg, es als Ganzes zu übergeben. Es geht nicht um die Leistung, sondern um Lesbarkeit und Wartbarkeit. Siehe auch die Gesetz der Demeter was zu einer lockereren Abhängigkeit vom übergebenen Objekt führen kann.
Nitin Pandey
Wie andere gesagt haben, hängt es davon ab, aber meiner Erfahrung nach erschwert das Übergeben ganzer Objekte das Lesen und Verwalten von Code.
Betrachten wir diese Methode getUserDetails(User user) die sich auf wenige Methoden wie stützt getUserAddress(User user)getUserFamilyInfo(User user) usw., die sich weiter mit verschiedenen Datenquellen verbinden können, um die Informationen abzurufen.
Es gibt keinen einfachen Weg, das zu wissen getUserFamilyInfo braucht nur userId oder es braucht userId Und lastName oder etwas anderes aus user wenn das gesamte Objekt übergeben wird. Es macht es schwierig, Abhängigkeiten zwischen verschiedenen Diensten zu verstehen und Refactoring durchzuführen.
Ich bevorzuge es, einzelne Argumente zu übergeben, wenn count weniger als 3 ist, oder ein dto zu erstellen, wenn eine Handvoll Eigenschaften von einem sehr großen Objekt benötigt werden.
14496400cookie-checkÜbergeben des gesamten Objekts vs. Übergeben der Eigenschaft des Objektsyes
Ich denke, die erste Option ist besser. Die äußere Welt muss nicht wissen, was Ihre Funktion intern mit dem Objekt macht (dh auf welche Felder sie zugreift.)
– TheLostMind
15. Januar 2014 um 11:30 Uhr
Es richtet sich ganz nach Ihren Bedürfnissen. Wenn Sie nicht möchten, dass die andere Methode die Felder Ihres Objekts ändert, übergeben Sie die Objektreferenz nicht. Übergeben Sie einfach die erforderlichen Werte. Wenn nicht, dann ist es besser, die Objektreferenz zu übergeben und die Werte davon nach Bedarf zu verwenden, anstatt so viele Parameter im Methodenaufruf hinzuzufügen.
– Raul
15. Januar 2014 um 11:31 Uhr
Es hat sich bewährt, den Code so einfach verständlich und klar wie möglich zu gestalten. In diesem Fall vermute ich, dass es keinen Leistungsunterschied gibt oder er zu gering ist, um ihn zu messen.
– Peter Lawrey
15. Januar 2014 um 11:37 Uhr