Wie lang sollten Variablen/Funktions/Klassen-namen maximal sein?



  • NamePropertyChangeEventHandler
    DependencyPropertyConverter

    mit der .Net geht schon einiges #gg

    public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(ClassName), new UIPropertyMetadata(ClassName.TitleValueChanged));
    private static void TitleValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    


  • naja... begin() bei einer Iteratorklasse ist relativ eindeutig.

    genauso wie ein clear() bei einer Liste nicht removeAllElementsFromListAndSetSizeToNull() heissen muss 😉

    wie jemand hier bereits gesagt hat: so kurz wie moeglich, aber so lang wie noetig.
    Auf biegen und brechen kurze Methodennamen ist genauso kontraproduktiv wie eine halbe Doku als Methodenname



  • Badestrand schrieb:

    Mir wäre er zu lang, einfach weil sich deshalb Funktionsaufrufe unheimlich in die Länge ziehen können,z.B. obj.doThisOrThaT( cont.getFirstElementIterator(), cont.getLastElementIterator(), true, 17 );

    first = cont.getFirstElementIterator();
    last = cont.getLastElementIterator();
    obj.doThisOrThaT( first, last, true, 17 );
    

    Edit:
    Wenn wir schon ueber guten Stil reden:
    http://blog.choonkeat.com/weblog/2007/08/true-false-para.html

    True False parameters

    Every so often, I get the chance to use functions that accepts a nondescript boolean as parameter... or *gasp* a sequence of nondescript booleans.

    api.connect( true )

    It's a chore for the maintainer (usually my future self) to have to look up what "true" meant. IDEs might be helpful at this point, bringing up code hints and what not.. unless of cos the function declaration itself isn't exactly perfect...

    def connect(bool)
    ...
    end

    I've finally come round to do myself a favor (ok, I AM going to be the maintainer) by using self-explanatory truthy / falsey values instead

    api.connect( :auto_retry ) # true
    api.connect( !:auto_retry ) # false

    Reads better. No?

    Die STL oder allgemein C/C++ Libs-Funktionen sind ganz besonders schlimm. Z.B. strncpy oder vsprintf, gibt aber noch schlimmere Namen. Diese Namen kommen halt aus einer Zeit ohne Autovervollstaendigung, aus einer Zeit in der Programmierer noch mit einfachen Texteditoren programmiert haben.

    Der Name einer Funktion/Methode sollte so lang sein das man ohne die Dokumentation sehen kann was sie macht. Z. B.

    strcpy > copyString(dest, source)
    strncpy > copyString(dest, source, num)
    vsprintf > formatPrint(string, format, arg)
    vprintf > formatPrint(format, arg)

    So wuerde es aussehen, wenn man in C Funktionen ueberladen koennte, was ja leider nicht geht. Man sollte immer beachten dass man Programme fuer Menschen schreibt und nicht fuer den Computer/Compiler. Es ist die Aufgabe des Compilers das Programm dann fuer den Computer zu uebersetzen.



  • DEvent schrieb:

    Die STL oder allgemein C/C++ Libs-Funktionen sind ganz besonders schlimm. Z.B. strncpy oder vsprintf, gibt aber noch schlimmere Namen.

    mein favorit ist immer noch 'strpbrk()'
    🙂



  • wobei ich strcpy eigentlich ganz ok finde. str steht für string und cpy für copy - ist trivial lesbar.

    viel schlimmer sind inkonsistente namen und parameter reihenfolge.

    PS:
    strpbrk ist natürlich fürchterbar.



  • ~fricky schrieb:

    Badestrand schrieb:

    Das natürlich, aber "GetFirstElementIterator" erinnert doch stark an das von camper erwähnte "begin" aus der STL.

    wer die STL nicht kennt, käme nie im leben darauf, in welchem zusammenhang das schlichte wörtchen 'begin' dort verwendet wird.

    Och, so frech bin ich einfach mal, dass ich STL-Kenntnis voraussetze.

    DEvent schrieb:

    Wenn wir schon ueber guten Stil reden:
    http://blog.choonkeat.com/weblog/2007/08/true-false-para.html

    Stimmt, muss ich mir auch mal angewöhnen, true/false als Parameter sind leider wirklich verflucht nichts-sagend 😞



  • Badestrand schrieb:

    ~fricky schrieb:

    Badestrand schrieb:

    Das natürlich, aber "GetFirstElementIterator" erinnert doch stark an das von camper erwähnte "begin" aus der STL.

    wer die STL nicht kennt, käme nie im leben darauf, in welchem zusammenhang das schlichte wörtchen 'begin' dort verwendet wird.

    Och, so frech bin ich einfach mal, dass ich STL-Kenntnis voraussetze.

    okay, bei 'nem durchschnitts c++ coder kann man das wohl voraussetzen, aber sonst wohl kaum. um welche sprache geht es hier überhaupt?
    🙂



  • Bei einer anderen Sprache benutzt man dann natürlich nicht begin/end, sondern die für diese Sprache gebräuchlichen Bezeichner.



  • DEvent schrieb:

    Wenn wir schon ueber guten Stil reden:
    http://blog.choonkeat.com/weblog/2007/08/true-false-para.html

    True False parameters

    Every so often, I get the chance to use functions that accepts a nondescript boolean as parameter... or *gasp* a sequence of nondescript booleans.

    api.connect( true )

    It's a chore for the maintainer (usually my future self) to have to look up what "true" meant. IDEs might be helpful at this point, bringing up code hints and what not.. unless of cos the function declaration itself isn't exactly perfect...

    def connect(bool)
    ...
    end

    I've finally come round to do myself a favor (ok, I AM going to be the maintainer) by using self-explanatory truthy / falsey values instead

    api.connect( :auto_retry ) # true
    api.connect( !:auto_retry ) # false

    Reads better. No?

    Wenn "auto_retry" in dem Beispiel einfach nur eine globale Bool-Konstante ist, dann finde ich das schlimmer als einfach "connect(true)". Grund: es ist nicht typesafe.
    Wenn es enums sind ist es OK, vorausgesetzt enums in der jeweiligen Sprache sind typesafe.

    Warum ich ein einfaches "true" im nicht-typesafe Fall vorziehe ... es passiert sonst ganz sicher (Murphy und faule/dumme Programmierer sorgen da schon dafür) dass solche Konstanten an Stellen hergenommen werden wo sie keinen Sinn machen. Und das finde ich persönlich schlimmer als wenn man nachgucken muss was "true" an der Stelle nun heisst.

    Falls man die API nicht anpassen kann (weils keine eigene API ist oder damit legacy-Code nicht bricht) kann man es immer noch mit lokalen Konstanten machen wenn man es übersichtlicher haben möchte:

    bool autoRetry = true;
        api.connect(autoRetry);
    

  • Administrator

    pumuckl schrieb:

    Dravere schrieb:

    Zentrale Funktionen sollten kurz und eindeutig sein, nicht so zentrale Funktionen können ruhig auch mal etwas länger sein.

    Wenn "zentral" bei dir gleichbedeutend ist mit "häufig benutzt und allseits bekannt" dann stimme ich dem zu.

    Genau das meinte ich.

    Bei bool Parametern verwende ich unterschiedliche Systeme. Wenn es klar aus dem Funktionsnamen herauskommt, dann lasse ich es, also z.B:

    use_default(true);
    // oder
    set_enabled(false);
    

    Wenn es dagegen nicht klar ist, vor allem wenn es meherere Parameter hat, dann setze ich einfach einen Kommentar dazu:

    create_object_x("Test",    // Title
                    342343,    // ID
                    true,      // Selfdelete
                    false,     // Kill everything else too
                    50);       // Amount of blood.
    

    Das mache ich sowieso noch oft, das ich probiere die einzelnen Parameter zu dokumentieren. So ist es gleich ersichtlich, was hier für was steht.

    Grüssli



  • Dravere schrieb:

    create_object_x("Test",    // Title
                    342343,    // ID
                    true,      // Selfdelete
                    false,     // Kill everything else too
                    50);       // Amount of blood.
    

    mach dir doch #defines, enums o.ä. um dualität für spezielle fälle auszudrücken. z.b. yes/no, on/off, SelfDelete.YES/SelfDelete.NO oder sowas. ich finde 'true' und 'false' sind für's ein- und ausschalten von irgendwas nicht so toll. aber das ist natürlich ansichtssache.
    🙂


  • Administrator

    ~fricky schrieb:

    mach dir doch #defines, enums o.ä. um dualität für spezielle fälle auszudrücken. z.b. yes/no, on/off, SelfDelete.YES/SelfDelete.NO oder sowas. ich finde 'true' und 'false' sind für's ein- und ausschalten von irgendwas nicht so toll. aber das ist natürlich ansichtssache.
    🙂

    Hmmm ... soll das dann am Ende so aussehen:

    #define TITLE(x) x
    #define ID(x) x
    #define BLOOD_AMOUNT(x) x
    
    bool const SELF_DELETE = true;
    bool const DO_NOT_SELF_DELETE = false;
    bool const KILL_EVERYTHING = true;
    bool const DO_NOT_KILL_EVERYTHING = false;
    
    create_object_x(TITLE("Test"),
                    ID(342343),
                    SELF_DELETE,
                    DO_NOT_KILL_EVERYTHING,
                    BLOOD_AMOUNT(50));
    

    Hässlich ...
    Da sind mir meine Kommentare viel lieber!

    Denn "Test" ist genauso nichts aussagen wie true oder 50 . Es ist ein Wert, welcher übergeben wird, was er aber bewirkt, kommt überhaupt nicht hervor!

    Grüssli



  • grade bei langen Parameterlisten kann ich durchaus verstehen dass man jeden Parameter kommentiert was er bewirken soll - wenn man davon ausgeht dass jemand der den Code später verstehen soll keine IDE hat mit der er die Deklaration der entsprechenden Funktion schnell erreichen kann, oder wenn diese Deklaration den Sinn der Parameter nicht hinreichend erläutert.

    denn mindestens genauso schlimm (in meinen Augen schlimmer) wie Aufrufe á la connect(true, false); sind Funktionsdeklarationen á la

    bool connect(bool b1, bool b2)
    

    Super, da weiß man sofort was die parameter zu bedeuten haben...

    bool connect(bool encrypt, bool reconnect_on_fail)
    

    Aha! das sagt schon alles - und wenn mir die IDE beim mouse-over das anzeigt oder mich schnell zu der Deklaration bringen kann, brauch ich auch nicht unbedingt irgendwelche #defines um mir die Wahrheitswerte zu maskieren oder kommentare die aus einem Einzeiler einen Dreizeiler machen etc.

    richtig Böse wird sowas dann, wenn man sich vertut oder (was natürlich extra eklig wäre) sich das Interface ändert (oder man eine falsche Redeklaration vornimmt):

    bool connect(bool send_plain_text, bool one_try_only)
    
    connect(DO_ENCRYPTION, TRY_RECONNECT); //die #defines stimmen nicht, oder doch?
    connect( true,   //send plain text (?)
             false); //more than one try (?)
    

    Autsch!

    in solchen Fällen verletzen selbstgebastelte #defines und Kommentare (die eh dazu tendieren sich nicht zu ändern wenn sich der zugehörige Code ändert) das DRY Prinzip.

    IMHO sollten sich daher Funktionen und ihre Parameter selbst erklären und dem Aufrufer das nötige Werkzeug liefern um unkompliziert herauszufinden was geschieht, statt ihn zu ermutigen, duplizierte Informationen zu schaffen, die abseits der Funktion selbst gepflegt werden.



  • pumuckl schrieb:

    grade bei langen Parameterlisten kann ich durchaus verstehen dass man jeden Parameter kommentiert was er bewirken soll - wenn man davon ausgeht dass jemand der den Code später verstehen soll keine IDE hat mit der er die Deklaration der entsprechenden Funktion schnell erreichen kann

    Warum sollte man auf so jemanden rücksicht nehmen?

    Das connect wäre über flags übrigens am sinnvollsten lösbar:

    connect(SOCKET_AUTO_RECONNECT | SOCKET_USE_ENCRYPTION);

    viel schöner und vorallem type-safe machbar.


Anmelden zum Antworten