Vor langer Zeit habe ich einen Artikel gelesen (ich glaube, ein Blogeintrag), der mich auf die "richtige" Spur bei der Benennung von Objekten gebracht hat: Seien Sie sehr skrupellos bei der Benennung von Dingen in Ihrem Programm.
Wenn meine Anwendung beispielsweise (als typische Geschäftsanwendung) Benutzer, Unternehmen und Adressen handhabt, hätte ich eine User
-, eine Company
- und eine Address
-Domänenklasse - und wahrscheinlich irgendwo eine UserManager
, ein CompanyManager
und ein AddressManager
werden eingeblendet, die diese Dinge handhaben.
Können Sie also sagen, was diese UserManager
, CompanyManager
und AddressManager
tun? Nein, da Manager ein sehr allgemeiner Begriff ist, der zu allem passt, was Sie mit Ihren Domain-Objekten tun können.
Der Artikel, den ich las, empfahl, sehr spezifische Namen zu verwenden. Wenn es sich um eine C++ - Anwendung handelte und die Aufgabe von UserManager
darin bestand, Benutzer zuzuweisen und vom Haufen zu befreien, würden die Benutzer nicht verwaltet, sondern ihre Geburt und ihren Tod geschützt. Hmm, vielleicht könnten wir das UserShepherd
nennen.
Oder vielleicht besteht die Aufgabe von UserManager
darin, die Daten jedes Benutzerobjekts zu untersuchen und die Daten kryptografisch zu signieren. Dann hätten wir ein UserRecordsClerk
.
Jetzt, da diese Idee bei mir angekommen ist, versuche ich sie anzuwenden. Und finde diese einfache Idee erstaunlich schwer.
Ich kann beschreiben, was die Klassen tun und (solange ich mich nicht mit Quick & Dirty Coding beschäftige), dass die Klassen, die ich schreibe, genau eines tun . Was ich von dieser Beschreibung zu den Namen vermisse, ist eine Art Katalog von Namen, ein Vokabular, das die Konzepte den Namen zuordnet.
Letztendlich hätte ich gerne so etwas wie einen Musterkatalog im Kopf (häufig liefern Entwurfsmuster leicht die Objektnamen, z. B. eine - Fabrik )
Kindermädchen - Hilft Objekten, nach der Erstellung den Status "Verwendbar" zu erreichen - zum Beispiel durch Verkabelung mit anderen Objekten
usw. usw.
Wie gehen Sie mit diesem Problem um? Haben Sie einen festen Wortschatz, erfinden Sie spontan neue Namen oder denken Sie darüber nach, Dinge zu benennen, die nicht so wichtig oder falsch sind?
P .: Ich interessiere mich auch für Links zu Artikeln und Blogs, die das Thema diskutieren. Zunächst ist hier der ursprüngliche Artikel, der mich zum Nachdenken brachte: Benennen von Java - Klassen ohne 'Manager'
Hier ist eine kleine Zusammenfassung dessen, was ich in der Zwischenzeit aus dieser Frage gelernt habe.
Weitere Artikel/Bücher zu diesem Thema:
Und eine aktuelle Liste von Namenspräfixen/Suffixen, die ich (subjektiv!) Aus den Antworten gesammelt habe:
Und ein guter Tipp für die Straße:
Keine Namenslähmung bekommen. Ja, Namen sind sehr wichtig, aber nicht wichtig genug, um viel Zeit damit zu verschwenden. Wenn Sie sich in 10 Minuten keinen guten Namen einfallen lassen, fahren Sie fort.
Ich habe eine ähnliche Frage gestellt , aber wenn möglich, versuche ich, die Namen bereits im .NET-Framework zu kopieren, und suche nach Ideen im Java und Android Frameworks.
Es scheint, dass Helper
, Manager
und Util
die unvermeidlichen Substantive sind, die Sie zur Koordinierung von Klassen anhängen, die keinen Status enthalten und im Allgemeinen prozedural und statisch sind. Eine Alternative ist Coordinator
.
Sie könnten besonders lila Prosey mit den Namen bekommen und für Dinge wie Minder
, Overseer
, Supervisor
, Administrator
und Master
, aber wie ich sagte, ich Behalten Sie es lieber so bei, wie Sie es gewohnt sind.
Einige andere gebräuchliche Suffixe (sofern dies der richtige Begriff ist), die Sie auch im .NET-Framework finden, sind:
Builder
Writer
Reader
Handler
Container
Sie können einen Blick auf source-code-wordle.de werfen. Dort habe ich die am häufigsten verwendeten Suffixe von Klassennamen des .NET-Frameworks und einiger anderer Bibliotheken analysiert.
Die Top 20 sind:
Ich bin alles für gute Namen, und ich schreibe oft darüber, wie wichtig es ist, bei der Auswahl von Namen für Dinge sehr vorsichtig zu sein. Aus dem gleichen Grund bin ich bei der Benennung von Dingen vorsichtig mit Metaphern. In der ursprünglichen Frage sehen "Factory" und "Synchronizer" wie gute Namen für das aus, was sie zu bedeuten scheinen. "Hirte" und "Kindermädchen" sind jedoch nicht, weil sie auf Metaphern basieren. Eine Klasse in Ihrem Code kann nicht wörtlich ein Kindermädchen sein; du nennst es ein Kindermädchen, weil es sich um einige andere Dinge kümmert, ähnlich wie ein Kindermädchen im wirklichen Leben um Babys oder Kinder. Das ist in informeller Sprache in Ordnung, aber meiner Meinung nach nicht in Ordnung, um Klassen im Code zu benennen, die von wem gepflegt werden müssen, der weiß, wann.
Warum? Weil Metaphern kulturabhängig sind und oft auch individuell. Für Sie kann es sehr klar sein, eine Klasse als "Kindermädchen" zu bezeichnen, aber für andere ist es vielleicht nicht so klar. Darauf sollten wir uns nicht verlassen, es sei denn, Sie schreiben Code, der nur für den persönlichen Gebrauch bestimmt ist.
In jedem Fall kann eine Konvention eine Metapher machen oder brechen. Die Verwendung von "factory" selbst basiert auf einer Metapher, die es aber schon eine ganze Weile gibt und die derzeit in der Programmierwelt ziemlich bekannt ist. Daher würde ich sagen, dass die Verwendung sicher ist. "Kindermädchen" und "Hirte" sind jedoch inakzeptabel.
Wir könnten ohne xxxFactory
, xxxManager
oder xxxRepository
Klassen auskommen, wenn wir die reale Welt richtig modellieren würden:
Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
.Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
.OfType<User>().CreateNew("John Doe");
;-)
Es klingt wie ein rutschiger Hang zu etwas, das auf thedailywtf.com, "ManagerOfPeopleWhoHaveMortgages" usw. gepostet wird.
Ich nehme an, es ist richtig, dass eine monolithische Manager-Klasse kein gutes Design ist, aber die Verwendung von 'Manager' ist nicht schlecht. Anstelle von UserManager können Sie auch UserAccountManager, UserProfileManager, UserSecurityManager usw. angeben.
'Manager' ist ein gutes Wort, weil es deutlich zeigt, dass eine Klasse kein reales 'Ding' darstellt. 'AccountsClerk' - wie soll ich feststellen, ob es sich um eine Klasse handelt, die Benutzerdaten verwaltet, oder ob sie jemanden repräsentiert, der für seinen Job ein AccountsClerk ist?
Da Sie an Artikeln in diesem Bereich interessiert sind, könnte Sie Steve Yegges Meinungsartikel "Hinrichtung im Königreich der Substantive" interessieren:
http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
Wenn ich darüber nachdenke, Manager
oder Helper
in einem Klassennamen zu verwenden, stelle ich fest, dass es sich um einen Codegeruch handelt, der bedeutet, dass ich noch nicht die richtige Abstraktion gefunden habe und/oder gegen die Richtlinie verstoße. Prinzip der Einzelverantwortung , so dass das Umgestalten und der Aufwand für das Design häufig die Benennung erheblich vereinfacht.
Aber selbst gut gestaltete Klassen benennen sich nicht (immer) selbst, und Ihre Auswahl hängt teilweise davon ab, ob Sie Geschäftsmodellklassen oder Klassen für technische Infrastruktur erstellen.
Geschäftsmodellklassen können schwierig sein, da sie für jede Domäne unterschiedlich sind. Es gibt einige Begriffe, die ich häufig verwende, wie Policy
für Strategieklassen innerhalb einer Domäne (z. B. LateRentalPolicy
), aber diese ergeben sich normalerweise aus dem Versuch, eine " allgegenwärtige Sprache zu erstellen ", die Sie mit Geschäftsbenutzern teilen können, indem Sie Klassen entwerfen und benennen, damit sie reale Ideen, Objekte, Aktionen und Ereignisse modellieren.
Technische Infrastrukturklassen sind etwas einfacher, weil sie Bereiche beschreiben, die wir sehr gut kennen. Ich ziehe es vor, Entwurfsmusternamen in die Klassennamen einzubeziehen, wie _InsertUserCommand,
CustomerRepository,
_ oder _SapAdapter.
_. Ich verstehe die Bedenken hinsichtlich der Kommunikation der Implementierung anstelle von Absichten, aber Entwurfsmuster verbinden diese beiden Aspekte des Klassenentwurfs - Zumindest, wenn Sie mit Infrastruktur zu tun haben und das Implementierungsdesign transparent sein soll, auch wenn Sie die Details verbergen.
Mit Mustern, wie sie in GOF-Buch definiert sind, vertraut zu sein und Objekte danach zu benennen, bringt mir einen weiten Weg, Klassen zu benennen, zu organisieren und Absichten zu kommunizieren. Die meisten Menschen werden diese Nomenklatur (oder zumindest einen Großteil davon) verstehen.
Wenn ich keinen konkreteren Namen für meine Klasse finden kann als XyzManager, wäre dies ein Punkt für mich, um zu überdenken, ob dies wirklich eine Funktionalität ist, die in einer Klasse zusammengehört, d. H. Ein architektonischer 'Codegeruch'.
Ich denke, das Wichtigste ist: Ist der Name beschreibend genug? Kannst du anhand des Namens erkennen, was die Klasse tun soll? Die Verwendung von Wörtern wie "Manager", "Service" oder "Handler" in Ihren Klassennamen kann als zu allgemein angesehen werden. Da sie jedoch von vielen Programmierern verwendet werden, ist es auch hilfreich zu verstehen, wofür die Klasse gedacht ist.
Ich selbst benutze das Fassadenmuster schon oft (zumindest glaube ich, dass es so heißt). Ich könnte eine User
-Klasse haben, die nur einen Benutzer beschreibt, und eine Users
-Klasse, die meine "Sammlung von Benutzern" verfolgt. Ich nenne die Klasse nicht UserManager
, weil ich Manager im wirklichen Leben nicht mag und nicht daran erinnert werden möchte :) Die einfache Verwendung des Pluralformulars hilft mir zu verstehen, was die Klasse tut.
C # -spezifisch fand ich "Framework-Entwurfsrichtlinien: Konventionen, Redewendungen und Muster für wiederverwendbare .NET-Bibliotheken" , um viele gute Informationen über die Namenslogik zu erhalten.
Was das Finden dieser spezifischeren Wörter angeht, verwende ich oft einen Thesaurus und springe durch verwandte Wörter, um zu versuchen, ein gutes zu finden. Ich versuche jedoch, nicht zu viel Zeit damit zu verbringen, während ich mich weiter entwickle, finde ich bessere Namen oder stelle manchmal fest, dass SuchAndSuchManager
wirklich in mehrere Klassen aufgeteilt werden sollte, und dann den Namen dieser veralteten Klasse wird zu einem Non-Issue.
Ich glaube, das Entscheidende dabei ist, innerhalb der Sichtbarkeit Ihres Codes konsistent zu sein, dh solange jeder, der Ihren Code betrachten/bearbeiten muss, Ihre Namenskonvention versteht, sollte dies in Ordnung sein, auch wenn Sie sich dafür entscheiden, sie aufzurufen 'CompanyThingamabob' und 'UserDoohickey'. Der erste Schritt, wenn Sie für eine Firma arbeiten, besteht darin, zu prüfen, ob es eine Firmenkonvention zur Benennung gibt. Wenn es keine gibt oder Sie nicht für ein Unternehmen arbeiten, erstellen Sie Ihre eigenen Begriffe mit für Sie sinnvollen Begriffen, geben Sie sie an ein paar vertrauenswürdige Kollegen/Freunde weiter, die zumindest beiläufig codieren, und nehmen Sie alle sinnvollen Rückmeldungen auf.
Es ist ein kleiner Fehler in meinem Buch, die Konvention eines anderen anzuwenden, auch wenn sie allgemein akzeptiert wird, wenn sie nicht von der Seite springt. Zuallererst muss ich meinen Code verstehen, ohne auf andere Dokumentationen zu verweisen, aber gleichzeitig muss er allgemein genug sein, damit er nicht für jemanden unverständlich ist, der auf demselben Gebiet in derselben Branche tätig ist.
Ich würde die Muster berücksichtigen, die Sie für Ihr System verwenden, und die Namenskonventionen/Katalogisierung/Gruppierung von Klassen von Tendenzen werden durch das verwendete Muster definiert. Persönlich halte ich mich an diese Namenskonventionen, da sie die wahrscheinlichste Möglichkeit für eine andere Person sind, meinen Code abzurufen und damit zu arbeiten.
Zum Beispiel könnte UserRecordsClerk besser als Erweiterung einer generischen RecordsClerk-Schnittstelle erklärt werden, die sowohl UserRecordsClerk als auch CompanyRecordsClerk implementieren und sich dann darauf spezialisieren, dh man kann die Methoden in der Schnittstelle betrachten, um zu sehen, wozu die Unterklassen im Allgemeinen dienen.
Informationen finden Sie in einem Buch wie Design Patterns . Es ist ein ausgezeichnetes Buch und kann Ihnen dabei helfen, herauszufinden, wo Sie mit Ihrem Code sein wollen - wenn Sie ihn nicht bereits verwenden! ;O)
Ich gehe davon aus, dass, solange Ihr Muster gut ausgewählt ist und soweit angemessen verwendet wird, nicht erfinderische, einfache Klassennamen ausreichen sollten!