05 Jul
2008

Einzeilige Methoden?

 

In Stelle immer wieder fest dass es eine ziemlich eingefahrene Meinung dazu gibt ab wann sich eine eigene Methode lohnt und wann nicht. Meist heißt es dass für eins bis drei Zeilen keine Methode notwendig ist und man durch einen Methoden Aufruf ja auch Performance Einbußen hat.

Ja, dieser Ansicht war ich früher auch. Problem an der Sache ist einfach, dass man auch bei wenig Zeilen oft manchmal nicht direkt den Zweck dahinter erkennt. Also müsste man entsprechende Kommentare schreiben die erklären was dort eigentlich passiert.

Hier ein kleines Beispiel welches ich gerade geschrieben hatte.

public void Register(Type interfaceType, Type implementationType, bool isStatic)
{
    lock (servicesLock)
    {
        EnsureValidInterface(interfaceType);
        if (implementationType.FindInterfaces(
                     (m, criteria) => m.Equals(interfaceType), null).Length == 0)
        {
            // Do Some Magic
        }
        services.Add(interfaceType, new IoCInfo(implementationType, isStatic));
    }
}

Hier muss dass if-Statement schon sehr genau angesehen werden damit einem klar wird was dort eigentlich überprüft wird. Somit wird der Fluss beim Lesen doch sehr gestört weil ich erst einmal analysieren muss was da passiert.

Ein kleiner Kommentar drüber und schon wüsste man was passiert. Der Kommentar müsste ungefähr so lauten "Wird das angegebene Interface implementiert?". Doch Hand auf's Herz, machen wir Entwickler dies wirklich? Des weiteren lesen wir doch noch den Code mit und versuchen ihn zu verstehen, somit haben wir nicht wirklich etwas gewonnen.

Jedoch besteht auch die Möglichkeit das if-Statement in eine eigene Methode auszulagern, deren Bezeichnung dazu noch ausdrückt was darin gemacht wird.

private bool InterfaceIsImplemented(Type interfaceType, Type implementationType)
{
    return implementationType.FindInterfaces(
           (m, criteria) => m.Equals(interfaceType), null).Length > 0;
}

Ein Kommentar bei der Verwendung wird nicht mehr gebraucht, die Methode spricht für sich selbst.

public void Register(Type interfaceType, Type implementationType, bool isStatic)
{
    lock (servicesLock)
    {
        EnsureValidInterface(interfaceType);
        if (!InterfaceIsImplemented(interfaceType, implementationType))
        {
            // Do some Magic
        }
        services.Add(interfaceType, new IoCInfo(implementationType, isStatic));
    }
}

Es wird direkt beim lesen des Codes deutlich was man prüft. Dass wie es gemacht wird, interessiert mich erst wenn es sich andersartig verhält. Des weiteren hat man ohne großen Aufwand die Möglichkeit geschaffen den Code an mehreren Stellen zu verwenden ohne in in per Copy & Paste zu vervielfältigen.

Die Performance-Frage ist in den allermeisten Fällen zu vernachlässigen. An erster Stelle sollte Funktion, Lesbarkeit sowie einfache Wartung des Codes stehen. Tritt dann ein Performance Problem auf so kann man sich dann immer noch damit beschäftigen, jedoch nicht ohne wirklich mit einem Profiler nachzumessen, da die Performance oft nicht da liegen bleibt wo man meint.

Nun mag man noch es wäre ja erhöhter Aufwand "so viel" in einzelnen Methoden zu packen, dem kann ich nur widersprechen. Visual Studio bietet seit der Version 2005 eingebautes Refactoring mit dem man mit einem Shortcut eine entsprechende Methode aus dem Code extrahieren kann. Beim schreiben des Codes kann man dies auch berücksichtigen den unbekannte Methodenrümpfe sind auch per Shortcut zu erstellen.

Es gibt AddIns wie ReSharper von JetBrains oder ReFactor! von DevExpress, die weit über die Möglichkeiten von Visual Studio hinausgehen und ein Vielfältigeres Refactoring des Codes erlauben.


Der Eintrag ist mir etwas Wert
 

Feedback

# re: Einzeilige Methoden?

left by Mathias at 7/5/2008 5:33 PM Gravatar
Hi Albert,

mein erster Gedanke beim Lesen Deines Codes: "Extension Method?"

Hier mal ein Vorschlag (nicht getestet und ohne Intellisense nur in der Kommentartextbox getippt... ;) ):

public static bool ImplementsInterface(this Type implementationType, Type interfaceType){ return implementationType.FindInterfaces( (m, criteria) => m.Equals(interfaceType), null).Length > 0;}

Damit würde Dein Code noch lesbarar:
if (!implementationType.ImplementsInterface(interfaceType))
{
// Do some Magic
}

# re: Einzeilige Methoden?

left by Albert Weinert at 7/5/2008 6:12 PM Gravatar
Klar, kann man machen. Jedoch Thema verfehlt ;)

# re: Einzeilige Methoden?

left by Thomas at 7/5/2008 9:18 PM Gravatar
Albert, das kann ich so unterschreiben. Lesbarkeit = Wartbarkeit, und nicht nur für andere wichtig, sondern auch für einen selbst - denn wir wissen ja alle, wie das mit eigenem Code ist, den man vor 1, 2 Jahren geschrieben hat ... ich achte immer darauf, einfachen und verständlichen Code zu schreiben, der insgesamt gut zu warten ist. Auch wenn ich dabei nicht alle Patterns implementiere, wie ich es gerne hätte oder sollte ;-)

# re: Einzeilige Methoden?

left by Sebastian Jancke at 7/6/2008 12:54 PM Gravatar
Albert,

es soll ja sogar Menschen geben, die eine Methode für jeden If- und For-Block fordern. Vielleicht ein bisschen zu dogmatisch, das ganze immer zu fordern, ist aber als rule-of-thumb einen Versuch wert.

Oftmals höre ich auch den Einwand, dass sehr kleine Methoden (mit schönen lesbaren Namen) schnell zu vielen Methoden in einem Objekt führen. Ich denke aber, dass wenn man sein Objekt fokusiert hält (SRP) und damit auch "klein", die paar mehr Methoden eigentlich kein Problem sein sollten.

Ich würde sogar soweit gehen zu fordern, dass alle Objekt-Invarianten immer durch eine Methode repräsentiert werden. Das führt zu sehr schönem, lesbaren Code ;-)

# re: Einzeilige Methoden?

left by Dani at 7/6/2008 2:31 PM Gravatar
Also zur Kapselung eines If-Statements genügt ja eigentlich die Einführung einer sprechenden booleschen Variable.
Methoden sollten doch immer dem Funktions-Gedanken folgen und irgend eine Funktion kapseln - und halt auch um Copy&Paste-Code zu vermeiden.

# re: Einzeilige Methoden?

left by Christian Kesselheim at 7/8/2008 9:29 AM Gravatar
Ich würde annehmen, dass kleine, private "Methödchen" wie diese sowieso vom JIT compiler ge-inlined werden und somit kaum auf die Performanz schlagen dürften. Siehe z.B. http://blogs.msdn.com/davidnotario/archive/2004/11/01/250398.aspx

# re: Einzeilige Methoden?

left by Bastian Waidelich at 7/9/2008 9:55 AM Gravatar
Die Methode macht den Code deutlich lesbarer. Fast wichtiger finde ich persönlich aber den Copy-Paste-Faktor: Je komplexer und unlesbarer ein Code-Ausschnitt, desto eher schleichen sich Bugs ein. Spätestens bevor dieser Code dann dupliziert wird, sollte er in eine Methode extrahiert werden. Ansonsten besteht nämlich zusätzlich die Gefahr, dass ermittelte Bugs nicht in allen Stellen gefixt werden.

# re: Einzeilige Methoden?

left by Peter Bucher at 7/23/2008 1:13 AM Gravatar
Salute Albert

Spät - jedoch volle Zustimmung.
Und ich schliesse mich vollends der Aussage von Bastian an.

# re: Einzeilige Methoden?

left by Wolfgang Hartmann at 8/10/2008 8:56 PM Gravatar
Schöner Code :)
Comments have been closed on this topic.