it-swarm.com.de

Code, der Nitpicks auf Lesbarkeit überprüft [eigentlich für DRY]

Ich habe heute eine Codeüberprüfung durchgeführt und festgestellt, dass der Code funktionieren würde , aber leicht lesbarer hätte gemacht werden können.

Das Beispiel war ungefähr wie folgt:

def group(x):
    GROUP_ALPHA = ('a', 'b', 'e', 'f', 'i', 'j', 'k', 'l')
    GROUP_BETA = ('m', 'n', 'o', 'p', 'q')
    GROUP_CHARLIE = ('x', 'y', 'z', 'aa', 'ab', 'ae', 'af')
    GROUP_DELTA = ('ag', 'ah', 'ai', 'aj')
    GROUP_ECHO = ('ak', 'al', 'am', 'an', 'ao', 'ar', 'as')

    if x in GROUP_ALPHA:
        return 'ALPHA'
    Elif x in GROUP_BETA:
        return 'BETA'
    Elif x in GROUP_CHARLIE:
        return 'CHARLIE'
    Elif x in GROUP_DELTA:
        return 'DELTA'
    Elif x in GROUP_ECHO:
        return 'ECHO'

Beachten Sie, dass jede Gruppe disjunkt ist.

Für mich wäre dies besser lesbar mit:

def group(x):
    GROUPS = {
        'ALPHA': ('a', 'b', 'e', 'f', 'i', 'j', 'k', 'l'),
        'BETA': ('m', 'n', 'o', 'p', 'q'),
        'CHARLIE': ('x', 'y', 'z', 'aa', 'ab', 'ae', 'af'),
        'DELTA': ('ag', 'ah', 'ai', 'aj'),
        'ECHO': ('ak', 'al', 'am', 'an', 'ao', 'ar', 'as')
    }
    for group_name, group_elements in GROUPS:
        if x in group_elements:
            return group_name

Soll ich das erwähnen? Der ursprüngliche Code funktioniert und wird unkritisch verwendet. Als ich recherchierte, bemerkte ich diese Antwort , was Folgendes bemerkt:

Jede Änderung kostet Geld. Das Umschreiben von Code, der funktioniert und wahrscheinlich nicht geändert werden muss, kann zu unnötigem Aufwand führen. Konzentrieren Sie sich auf die Abschnitte, die Änderungen unterliegen oder die für das Projekt am wichtigsten sind.

Dies würde darauf hinweisen, dass die Antwort Nein lautet, aber es scheint verschwenderisch, eine Codeüberprüfung durchzuführen und keinen besseren Weg vorzuschlagen, um Dinge zu tun, selbst wenn der ursprüngliche Weg "funktioniert". Persönlich möchte ich, dass mir jemand einen solchen Vorschlag macht.

Hinweis: Die obigen Beispiele wurden bearbeitet, seit die Frage zum ersten Mal geschrieben wurde. Auch jeder Eintrag ('a', 'b', etc.) ist eigentlich ein von Menschen lesbares str, das sich auf Geschäftslogik bezieht.

6
Shayaan

Das gegebene Beispiel macht meiner Meinung nach keinen großen Unterschied in der Lesbarkeit - tatsächlich ist es ziemlich umstritten, ob die zweite Variante wirklich besser lesbar ist als die erste. Es ist jedoch eindeutig eine Verbesserung, dem TROCKENEN Prinzip zu folgen, und das ist ein sehr gültiger Grund um den Code zu ändern.

Nehmen wir an, es ist beabsichtigt, mit all diesen Gruppen immer auf ähnliche Weise umzugehen, was ich für sehr wahrscheinlich halte. Nehmen wir auch an, dass es mindestens fünf dieser Gruppen gibt. Jetzt erhalten Sie die neue Anforderung, die Logik in etwas wie zu ändern

if lower(x) in GROUP_ALPHA:

dann müssen Sie im ersten Beispiel 5 Stellen ändern, sicherstellen, dass Sie sie identisch ändern und keinen Ort vergessen. Im zweiten Beispiel gibt es nur einen Ort zum Ändern, was definitiv eine Verbesserung darstellt. Wenn Sie einen Komponententest für diese Funktion oder speziell für die Änderung dieser Funktion schreiben möchten, erfordert die erste Variante 5 verschiedene Testfälle, um eine vollständige Abdeckung zu erzielen, und die zweite nur einen.

Noch einfacher - vorausgesetzt, Sie möchten nur eine weitere Gruppe hinzufügen - im ersten Beispiel müssen Sie zwei Stellen im Code ändern (einschließlich des Kopierens des gesamten Abschnitts "Suche"), im zweiten Beispiel müssen Sie nur die erweitern Wörterbuch.

Das Behalten von Code DRY ist nicht nur eine Frage des "Geschmacks" - es geht darum, Code in einen Zustand zu bringen, in dem es weniger wahrscheinlich ist, dass er zukünftige Kopfschmerzen verursacht. Und Codeüberprüfungen sind eine gute Gelegenheit für diese.

14
Doc Brown

Ein Vorteil von Codeüberprüfungen besteht in der Tat darin, bessere Methoden vorzuschlagen. Besser bedeutet natürlich verschiedene Dinge in verschiedenen Kontexten, kann aber Code enthalten, der besser lesbar ist, schneller ist, weniger Speicher verbraucht, guten Entwurfsprinzipien folgt, weniger komplex ist usw. Das Vorschlagen einer besser lesbaren Änderung ist ein perfektes Beispiel von etwas zu beachten während einer Codeüberprüfung.

Jede Änderung kostet Geld, aber auch der Versuch, schlecht geschriebenen Code in 6 Monaten zu entschlüsseln.

Denken Sie jedoch an Ihre Zielgruppe und stellen Sie fest, dass diese für Sie möglicherweise besser lesbar ist, für andere jedoch weniger lesbar (insbesondere, wenn Sie mit vielen Nachwuchsingenieuren zusammenarbeiten). Denken Sie auch an Ihre Anwendungsumgebung/-anforderungen, wenn Sie diese Änderungen vorschlagen. Während Ihre Lösung möglicherweise schneller ist, ist möglicherweise kein schnellerer Code erforderlich. Wenn das Wörterbuch immer nur 2 Schlüssel enthält, die einer Liste von 3 Elementen zugeordnet sind, ist die Leistung niemals ein Problem, unabhängig davon, wie Sie es eingerichtet haben. Es lohnt sich wahrscheinlich immer noch, darauf einzugehen, da der Rest Ihres Teams es das nächste Mal verwenden kann, aber stellen Sie fest, dass es nichts ist, worauf Sie sich konzentrieren sollten.

9
mmathis

Die vorgeschlagene Änderung führt zu einem subtilen Fehler. Ich denke, dies ist ein gutes Beispiel dafür, warum Vorschläge sorgfältig geprüft werden sollten.

Wenn x Mitglied mehrerer Gruppen ist, gibt das erste Beispiel die Gruppe first zurück, die in der expliziten Reihenfolge der if gefunden wurde. Im zweiten Beispiel werden die Gruppen in einer nicht angegebenen Reihenfolge überprüft (da die Wörterbücher nicht geordnet sind), sodass die zurückgegebene Gruppe nicht definiert ist. Dies ist besonders heimtückisch, da es möglicherweise die erwartete Ausgabe in Unit-Tests ist, dies kann sich jedoch auf einer anderen Plattform oder mit einem Versionsupdate ändern.

Das zugrunde liegende Problem ist, dass der neue Code die Absicht nicht klar kommuniziert. Wenn das erwartete Ergebnis tatsächlich nicht deterministisch ist, sollte es meiner Meinung nach in der Dokumentation klar kommuniziert werden, da dies definitiv gegen das "Prinzip der geringsten Überraschung" verstößt.

Wenn Sie andererseits erwarten, dass ein x in genau einer Gruppe erscheint, sollte meiner Meinung nach die Datenstruktur geändert werden, um dies klar zu kommunizieren, z.

def group(x):
    GROUPS = {
      'a': 'ALPHA', 
      'c': 'ALPHA',
      'd': 'ALPHA',
      'h': 'BETA', 
      'k': 'BETA', 
      'l': 'BETA'
    }
    return GROUPS[x]

Dies ist auch ein viel einfacherer Code, da die Annahmen eher in der Datenstruktur als in Iterationsschleifen codiert sind.

Trotzdem stimme ich zu, dass es eine gute Idee ist, Verbesserungen der Lesbarkeit in Codeüberprüfungen vorzuschlagen. Aber das sollten Sie wirklich in Ihrem Team besprechen.

6
JacquesB