Warum sollte es vorteilhaft sein, Objekte durch statische Methoden zu führen?

9

Warum sollte es von Vorteil sein, eine statische Methode zu verwenden und die Referenz als Parameter an ein Objekt zu übergeben, anstatt die Methode für ein Objekt aufzurufen?

Betrachten Sie die folgende Klasse, um zu verdeutlichen, was ich meine:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

Im Vergleich zu dieser alternativen Implementierung mit einer statischen Methode:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

Meine Frage ist nicht nur auf diese Klasse beschränkt; Jeder Punkt, an dem Sie ein Objekt übergeben würden, anstatt es für eine Methode aufzurufen, interessiert mich. Ist das jemals vorteilhaft? Wenn ja warum?

Addison Crump
quelle
1
Es fühlt sich an wie ein Codegeruch mit zwei Methoden, die genau dasselbe tun. Wenn die statische Methode einfach an die andere Methode delegiert würde, würde sie sich nutzlos anfühlen, aber nicht unbedingt "schlecht"
Nathan Merrill
13
@ NathanMerrill Ich denke, Sie verpassen den Punkt. Er fragt, ob es jemals eine Situation gibt, in der das Erstellen und Verwenden der zweiten Methode anstelle der ersten Methode vorzuziehen wäre.
@Mego Nicht nur die im Beispiel angegebenen Methoden; Ich frage, ob es einen Moment gibt, in dem die Verwendung statischer Methoden und das Übergeben von Objekten besser ist als das Aufrufen von Methoden für Objekte.
Addison Crump
Vermutlich fragen Sie speziell nach Java?
Enderland
3
Ich denke, diese Frage geht stillschweigend davon aus, dass objektorientierter Code eine Art Optimum ist. Ein prozeduraler oder funktionaler Ansatz würde natürlich zur Verwendung statischer Methoden führen. ... Das Duplizieren der Funktionalität zwischen einer statischen und einer Instanzmethode ist jedoch ziemlich dumm. Ich hoffe, das ist nur ein Beispiel und der eigentliche Code, über den Sie sprechen, ist nur statisch.
jpmc26

Antworten:

34

Ein triviales Beispiel: Wenn die übergebene Instanz zu Recht null sein kann und Sie die (nicht triviale) Behandlung dieser Instanz in die Methode einbeziehen möchten.

9000
quelle
1
Beispiel: String.Compare in C # (ich denke, es gibt etwas Ähnliches in Java)
edc65
Objects.equals () und Objects.compare () sind Beispiele in Java - sie gehören jedoch nicht zur ursprünglichen Klasse. In der Java - Standard - Bibliothek zumindest ist es üblich , eine Instanz Methode auf so etwas wie Objekt zu haben, aber dann eine statische Methode für ein Objekt s Klasse.
Daboross
20

In Ihrem Beispiel ist die Instanzmethode ein klarer Gewinner.

Im allgemeinen Fall kann ich mir einige Gründe vorstellen, aus denen eine statische Methode geeignet sein könnte:

  • Sie möchten die statische Methode in eine andere Klasse einfügen, da es sinnvoll ist, die Logik von den Daten zu trennen (Hinweis: Ihr Beispiel gehört nicht dazu).

  • Sie passieren zwei oder mehr Objekte und möchten betonen, dass sie gleich wichtig sind.

  • null ist ein gültiger Wert (wie vom Benutzer 9000 erläutert).

Heinzi
quelle
5

Es wäre ratsam, die Methoden, die den Status des Objekts ändern, als Instanzmethoden und nicht als statische Methode einzuschließen .

Wir können jedoch Beispiele für statische Methoden finden, die pureMethoden sind und das Objekt als Eingabe verwenden, beispielsweise wenn wir das Objekt basierend auf bestimmten Validierungsregeln instanziieren müssen. Beispielsweise verfügt .NET über die Methode DateTime.TryParse(String s, DateTime d)zum Validieren und Instanziieren des Objekts. Der Parameter DateTime dist jedoch explizit als gekennzeichnet out.

Ein anderer Fall kann sein, wenn wir die Objekte vergleichen und das gewünschte Objekt als Rückgabewert und nicht als booleschen / ganzzahligen Wert des Vergleichsergebnisses erhalten möchten, z Team.GetHigherScorer(teamA, teamB).IncreaseRanking(). Dies wird sauberer sein als:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(Der Einfachheit halber wird der Fall "herausgezogen").

Wunderglocke
quelle
1
Man übergibt kein "ganzes Objekt". Sie übergeben den Verweis an eine Stelle im Speicher, bei der es sich um eine sehr kleine Datenmenge handelt, die übergeben wird. Ich bin mir nicht sicher, welche Auswirkungen dies auf die Leistung hat, aber trotzdem ... auch, was bedeutet die Markierung "out"?
Addison Crump
1
Ich habe das Wort "ganz" aus meiner Aussage gestrichen, es war verwirrend. Ich habe nie Leistung oder Größe beabsichtigt, die Antwort basiert ausschließlich auf Programmierpraktiken. Wie auch immer, outist ein .NetSchlüsselwort, das als Parametermodifikator verwendet wird. Es gibt an, dass der Parameter als Referenz übergeben wird. Siehe für Details msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
Wonderbell
4
Der erste Satz ist einfach falsch. Wenn wir haben, class C { int x; static void M() { ist M perfekt in der Lage zuzugreifen x. Zum Beispiel int y = (new C()).x;ist legal.
Eric Lippert
@ EricLippert :) Ich bin sicher, Sie wissen, was ich meinte. Es ist erstaunlich, wie Meister zwischen den Zeilen lesen können. Vielleicht muss ich diesen Satz bearbeiten. Zur Verdeutlichung ist so etwas static void M() { this.x = 1; }nicht möglich.
Wunderglocke
1
@ Wonderbell: Nein, ich bin sicher, ich wusste nicht, was du meinst. Ich wusste was du geschrieben hast. Ich stelle fest, dass dies this.xnicht falsch ist, weil xnicht zugegriffen werden kann, sondern weil thises nicht existiert. Es ist überhaupt keine Frage des Zugangs , es ist eine Frage der Existenz .
Eric Lippert
4

Die Abhängigkeitsinjektion wäre ein guter Grund, den Aufruf der statischen Methode durchzuführen. Angenommen, die konkrete Implementierung von SomeClasshat eine Vererbungskette oder ist die Implementierung einer anderen Klasse. Sie können ein Modell eines Objekts verwenden, es zu Testzwecken übergeben, um sicherzustellen, dass Ihre Methode das tut, was es soll, und dann über diesen Status berichten.

Adam Zuckerman
quelle