Gibt es gute Techniken oder Tests für Benennungstypen?

23

Eine unangenehme, offene Frage, aber es ist ein Problem, gegen das ich immer stoße:

Software, die einfach zu warten und zu bedienen ist, ist eine gut konzipierte Software. Wenn Sie versuchen, ein Design intuitiv zu gestalten, müssen Sie die Komponenten so benennen, dass der nächste Entwickler auf die Funktion der Komponente schließen kann. Aus diesem Grund nennen wir unsere Klassen nicht "Type1", "Type2" usw.

Wenn Sie ein reales Konzept (z. B. einen Kunden) modellieren, ist dies im Allgemeinen so einfach wie die Benennung Ihres Typs nach dem real modellierten Konzept. Aber wenn Sie abstrakte Dinge erstellen, die systemorientierter sind, gehen Ihnen leicht die Namen aus, die sowohl leicht zu lesen als auch leicht zu verdauen sind.

Es wird (für mich) schlimmer, wenn ich versuche, Typenfamilien mit einem Basistyp oder einer Schnittstelle zu benennen, die beschreiben, was die Komponenten tun müssen, aber nicht, wie sie funktionieren. Dies führt natürlich dazu, dass jeder abgeleitete Typ versucht, die Art der Implementierung (z. B. IDataConnectionund SqlConnectionin .NET Framework) zu beschreiben. Wie können Sie jedoch etwas Kompliziertes ausdrücken, wie "Arbeiten durch Reflektion und Suchen nach bestimmten Attributen"?

Wenn Sie dann endlich einen Namen für den Typ ausgewählt haben, der Ihrer Meinung nach das beschreibt, was er versucht, fragt Ihr Kollege: "WTF macht das DomainSecurityMetadataProvidereigentlich ? "

Gibt es gute Techniken, um einen aussagekräftigen Namen für eine Komponente zu wählen, oder um eine Familie von Komponenten zu erstellen, ohne durcheinander geratene Namen zu erhalten?

Gibt es einfache Tests, die ich auf einen Namen anwenden kann, um ein besseres Gefühl dafür zu bekommen, ob der Name "gut" ist und für andere intuitiver sein sollte?

Paul Turner
quelle
20
Es hat sich gezeigt , dass sechs Techniken für mich funktionieren: 1) Verbringe viel Zeit damit, Namen zu erfinden. 2) Benutze Code-Reviews. 3) Zögere nicht, sie umzubenennen. 4) Verbringe viel Zeit damit, Namen zu erfinden. 5) Benutze Code-Reviews 6) Zögern Sie nicht, umzubenennen
Mücke
5
@gnat: Bitte poste deine Antwort als Antwort, damit wir sie abstimmen können.
S.Lott,
3
Ich benutze oft einen Thesaurus, wenn ich neue Entwicklungen mache, um gute Namen zu finden.
Dr. Wily's Apprentice
3
Ich versuche zu vermeiden, etwas "Manager" zu nennen. Alan Green und Jeff Atwood argumentieren, dass der Begriff überbeansprucht und zu vage ist, um Bedeutung zu vermitteln. Ich muss zustimmen.
Dr. Wily's Apprentice

Antworten:

41

Für die Benennung gibt es sechs Techniken , die sich bei mir bewährt haben:

  1. Verbringe viel Zeit damit, Namen zu erfinden
  2. Verwenden Sie Code-Überprüfungen
  3. zögern Sie nicht umzubenennen
  4. Verbringe viel Zeit damit, Namen zu erfinden
  5. Verwenden Sie Code-Überprüfungen
  6. zögern Sie nicht umzubenennen

PS. Für den Fall, dass Ihre API öffentlich sein wird, gilt das oben Gesagte davor - denn Sie wissen,

"Öffentliche APIs wie Diamanten sind für immer. Sie haben eine Chance, es richtig zu machen, also geben Sie Ihr Bestes ..." (Joshua Bloch, Wie man eine gute API entwirft und warum es wichtig ist )

Mücke
quelle
1
Falls es sich um eine öffentliche API handelt, gibt es drei zusätzliche Techniken, die Sie verwenden können ...
UncleZeiv
1
@ OnkelZeiv: wie ....?
FrustratedWithFormsDesigner
3
@FrustratedWithFormsDesigner: 1. verbringe viel Zeit damit, Namen zu erfinden 2. benutze Code-Reviews und 3. zögere nicht, sie umzubenennen
S.Lott
3
Diese Antwort hat mich im Allgemeinen überzeugt: Nein, es gibt keinen einfachen Weg, um die richtigen Namen zu finden. Ich versuche nur wirklich hart zu arbeiten.
Paul Turner
4
7. Zögern Sie nicht, Typen oder Funktionen neu zu entwerfen, wenn sich herausstellt, dass es unmöglich ist, einen richtigen Namen für sie zu finden. Gut gestalteter Code kann immer richtig benannt werden.
Joren
8

Mein Basistest ist, ob Sie die Funktion der Variablen nur mit Wörtern aus der Variablen beschreiben können:

Beispiel: Wenn DomainSecurityMetadataProvider entweder "Metadaten zur Domänensicherheit bereitstellt" oder "Metadaten zur Domänensicherheit bereitstellt", ist dies in Ordnung.

Es gibt jedoch Nuancen, die von Person zu Person variieren:

ZB ist original_team_code für mich der Code für das ursprüngliche Team, während es sich bei jemand anderem möglicherweise um den Originalcode für das Team handelt. Mein persönlicher Favorit war "UnsafeLegacyMutex", was ich als "Dies ist ein unsicherer Legacy-Mutex" und nicht als "Dies ist ein Mutex für ThreadUnsafe-Legacy-Code" lesen konnte.

Mein erweiterter Test besteht darin, die Variable in ein Forum / Wiki / Chat zu schreiben und die Leute raten zu lassen, was es bedeutet.

entwurde
quelle
7

Gibt es gute Techniken, um einen aussagekräftigen Namen für eine Komponente zu wählen, oder um eine Familie von Komponenten zu erstellen, ohne durcheinander geratene Namen zu erhalten?

Nicht wirklich.

Ein Tipp ist jedoch, "Passiv" zu vermeiden.

"DomainSecurityMetadataProvider" ist passiv. Es gibt kein Verb, sondern nur Substantive und Substantive, die als Adjektive verwendet werden.

"ProvideMetadataForDomainSecurity" ist aktiver. Es gibt ein Verb.

Objektorientierte Programmierung ist alles (wirklich) Nomen-Verb. Nomen == Objekt. Verb == method. Ein Klassenname ist also im Allgemeinen sehr "substantivisch". Diese Gewohnheit zu brechen und Verben einzufügen, ist schwierig.

Gibt es einfache Tests, die ich auf einen Namen anwenden kann, um ein besseres Gefühl dafür zu bekommen, ob der Name "gut" ist und für andere intuitiver sein sollte?

Ja. Sie haben in Ihrer Frage einen hervorragenden Test definiert. Fragen Sie andere Leute.

Früher haben wir dies als "Design-Komplettlösung" bezeichnet. Es war eine große, schweißtreibende Sache in einer Wasserfallmethode. Heutzutage sollte es mit agilen Methoden eine gewöhnliche Zusammenarbeit zwischen dem Autor und den Benutzern einer Klasse sein. Es dauert nicht lange und sollte auch nicht lange dauern. Das Diskutieren des Designs (und der Namen) vor dem Schreiben der Tests (und des Codes) verringert den Überraschungsfaktor und kann WTFs verhindern.

S.Lott
quelle
12
Ich bin mir nicht sicher, ob ich mit der Idee der passiven Stimme einverstanden bin. Klassen sind für mich sinnvoller als Substantive.
Deworde
7
Im Allgemeinen versuche ich, meine Typnamen in passiver Sprache zu halten, da dies dem Nomen-Verb-Stil von OOP entspricht. Ich würde meinen ProvideMetadataForDomainSecurity, ein schlechter Typ zu sein. Methodennamen sind in der Regel viel einfacher zu benennen, da ich Verben verwenden kann. Die Einschränkung der Sprache ist der Kern des Problems.
Paul Turner
So sehr ich es mag, Menschen als echten Test zu befragen, muss ich meine Kollegen mindestens zweimal am Tag nach Namen fragen. Ich hoffe auf etwas, das nicht die Zeit anderer Leute erfordert.
Paul Turner
2
Klassen sind als Substantive sinnvoll. Das Problem sind diese komplexen Klassen mit langen Substantiv-Adjektiv-Phrasen. Präpositionen können ebenfalls hilfreich sein.
S.Lott
2
Zusammenarbeit ist das Geheimnis guter Software. Zusammenarbeit braucht Zeit. Es gibt keinen Königsweg für gutes Schreiben.
S.Lott,
6

Verwendung eines Thesaurus

Sehr oft beziehe ich mich bei Neuentwicklungen auf einen Thesaurus, um geeignete Wörter zu finden, die meine Klassen und Methoden beschreiben.

Klassen, die hauptsächlich Operationslogik enthalten

Ich neige dazu, Klassen zu benennen, die hauptsächlich Operationsmethoden in einer Nomen-Verb-Struktur wie "EntityProvider", "EntityLocator" usw. bereitstellen.

Diese Klassen enthalten im Allgemeinen nicht viel Zustand.

Klassen, die state enthalten

Benutzeroberflächenbildschirme und Datenentitäten sind im Allgemeinen statusbehaftet. Daher benenne ich diese Klassen einfach mit einem Nomen- oder Adjektiv-Nomen-Muster.

Beispiele: Person, Mitarbeiter, Aktueller Mitarbeiter, Ehemaliger Mitarbeiter

Gebrauchsklassen

Klassen, die nur statische Methoden enthalten, werden im Allgemeinen als "Utility" -Klassen betrachtet, daher benenne ich sie durchweg mit dem Suffix "Utility".

Beispiele: NetworkUtilities, FileUtilities

Tests

Ich habe keine guten Tests, um zu entscheiden, ob etwas schlecht benannt ist, aber ich würde vorschlagen, ein einzelnes Substantiv und / oder ein einzelnes Verb im Namen zu verwenden und dann darüber nachzudenken, ob dieses Substantiv / Verb genau beschreibt, was Sie ' Umbenennung.

Wenn Sie der Meinung sind, dass die Klasse / Methode mehr enthält, als der Name angibt, muss diese Klasse / Methode möglicherweise überarbeitet werden.

Alan Green und Jeff Attwood haben über die Übel geschrieben, Klassen mit dem Suffix "Manager" zu benennen. Sie argumentieren, dass der Begriff "Manager" überstrapaziert und zu vage ist, um irgendetwas Sinnvolles zu vermitteln. Ich muss zustimmen.

Jeffs Artikel enthält auch eine Liste der vorgeschlagenen Richtlinien aus Steve McConnells Code Complete.

Variablen

Kürzlich habe ich mit längeren beschreibenden Variablen- / Parameternamen experimentiert, die Präpositionen wie "Of", "By", "For" usw. enthalten. Einige Beispiele sind nachstehend aufgeführt:

string firstNameOfEmployee;

string lastNameOfEmployee;

// here I nimbly avoid worrying about whether to call it "Id" or "ID" :)
int idOfEmployee;

decimal amountForDeposit;

Account accountForDeposit;

Ich finde, dass dies gut mit der Intellisense-Funktion von Visual Studio funktioniert, die es einfach macht, diese langen Namen einzugeben. Ich finde auch, dass es weniger Duplikationen von Variablennamenpräfixen gibt (z. B. personID, personFirstName, personLastName vs. idOfPerson, firstNameOfPerson, lastNameOfPerson), wodurch ein besserer "Hash" bereitgestellt wird, der Intellisense noch nützlicher macht.

Dr. Wily's Lehrling
quelle
1
Ich werde den Punkt über lange Variablennamen noch einmal unterstützen. Visual Studio (falls Sie es verwenden) macht dies zu einem Kinderspiel. Es ist viel weniger schädlich, lange Variablennamen zu haben, die explizit sind, als kurze Variablennamen, bei denen man überlegen oder untersuchen muss, was der Name tatsächlich bedeutet. Denken Sie auch an den Kontext. Ich würde lieber "peopleToDelete" als "listOfPeople" sehen. In Visual Studio wird Ihnen der Typ der Variablen angezeigt, ohne dass Sie ihn einschließen müssen.
John Bubriski
Ich mag auch nicht die ausgefeilte ungarische Notation, die Sie Variablennamen hinzugefügt haben. Es sollte mir egal sein, ob es sich bei einer Sammlung von Personen-IDs um ein ListArray IEnumerableoder um ein Array handelt ConcurrentQueue. Es sind eine Reihe von IDs, die ich aufzählen muss, und das Implementierungsdetail, wie sie gespeichert werden, ist unnötiges Kopfgepäck. Obwohl ich im Allgemeinen der Meinung bin, dass ein längerer Name, wenn er wesentlich aussagekräftiger ist, einem kürzeren, weniger eindeutigen Namen vorgezogen werden sollte.
Allon Guralnek
@Allon - Komisch, ich wollte meine Antwort auf der Grundlage von SkippyFires Kommentar überarbeiten. Ich stimme dir tatsächlich zu. Mein Beispiel erinnert an die ungarische Notation. Meine einzige Verteidigung ist, dass es einfach ist, den Code zu lesen und die beteiligten Datentypen zu verstehen, ohne dass eine IDE verfügbar ist, zum Beispiel, wenn ich ein Versionsverwaltungs-Diff durchlese. Das ist jedoch keine Entschuldigung. :) Ich werde mein Beispiel so überarbeiten, dass es in etwa wie der Vorname des Mitarbeiters, der Nachname des Mitarbeiters usw. aussieht
Dr. Wily's Apprentice
2

Wenn Sie dann einen Namen für den Typ ausgewählt haben, der Ihrer Meinung nach beschreibt, was er versucht, fragt Ihr Kollege: "WTF macht dieser DomainSecurityMetadataProvider tatsächlich?"

Welche Art von Namen erwarten Sie für eine komplexe und domänenspezifische Klasse? Dies ist ungefähr so ​​gut wie es nur geht, wenn Sie Ihren Klassennamen zu einem Satz machen (was alle glauben lässt, dass Sie einer einzelnen Klasse zu viel Verantwortung übertragen haben).

Ich würde in Betracht ziehen, Anbieter aus dem Namen zu streichen. Wenn speziell Metadaten erwähnt werden, weiß bereits jeder, dass Sie Reflektion verwenden. Sie könnten ein Wort prägnanter formulieren (oder möglicherweise in ein anderes Wort umwandeln - es ist eher ein Verbraucher als ein Anbieter von dem, was Sie geschrieben haben).

brian
quelle
Die fraglichen Metadaten stammen nicht aus der Reflexion (sondern beschreiben, wie Typen behandelt werden). Der Typ implementiert eine ISecurityMetadataProviderSchnittstelle, die als injizierbarer Punkt in der Sicherheitsinfrastruktur vorhanden ist, um dem Subsystem Informationen bereitzustellen. Die Benennung ist schwer.
Paul Turner,
Ich betrachte DomainSecurityMetadataProvideres als Anbieter von DomainSecurityMetadataObjekten, bei denen DomainSecurityMetadatasich Metadaten selbst befinden. Klarer und verständlicher Name. Ich muss nicht einmal wissen, was DomainSecurityMetadataist! Es ist nur ein Objekt, das dieser Anbieter zur Verfügung stellt. Das Entfernen eines ProviderSuffixes verbessert nicht die Lesbarkeit, im Gegenteil - reduzieren Sie es. Ohne dieses Suffix würde ich denken, dass es sich nur um einige Metadaten handelt (Containerobjekt für einige Metadaten), aber nicht um ein Objekt, von dem Metadaten abgerufen werden sollen (ein Anbieter).
Ruslan Stelmachenko
0

Verwenden Sie Metaphern, um Teile des Systems zu beschreiben. Sie werden nicht nur neue Analogien entdecken, sondern auch die Benennung erleichtern.

(Ich bin mir dessen bewusst, dass dies kein gutes Beispiel ist.) Sie können beispielsweise eine Variable oder einen Typ als aufrufen mailbox, der als Warteschlange für die empfangenen Nachrichten für eine Klasse dient.

Nimcap
quelle
-1

Eine Sache, bei der ich fest bin, ist, dass Namen NIEMALS falsch sein dürfen. Das beste Beispiel: Während eines Re-Factorings änderte sich eine Menge Code, und einige Variablen verweisen auf etwas anderes als die von ihnen vorgeschlagenen Namen.

Ziemlich bald verbrachte ein Programmierer einige Zeit damit, über einige sehr teure Datenbankaufrufe an bestimmte Daten zu gelangen, die bereits extrahiert und gespeichert worden waren. Ich habe alles umbenannt und plötzlich konnten wir eine Menge überkomplizierter und fehlerhafter Logik entfernen.

entwurde
quelle
1
Sie sollten diese Antwort löschen und in Ihre ursprüngliche Antwort
ändern
Ich denke, das ist eine andere Antwort als meine andere Antwort.
Deworde
-1

Hoffentlich gibt es selten Fälle, in denen Sie so intensiv über die Namen nachdenken müssen. Wenn solche Fälle auftreten, schreiben Sie einfach einen Absatz, in dem erklärt wird, was die Klasse tut. Im Gegensatz zu funktionsinternen Kommentaren oder Kommentaren auf Funktionsebene ändert sich der primäre Zweck einer Klasse selten, sodass das Risiko, dass Kommentare nicht mehr aktuell sind, relativ gering ist. Sie haben also den Luxus, ein paar Absätze zu schreiben oder sogar ASCII zu zeichnen, um zu erklären, was die Klasse tut.

kizzx2
quelle