Im Allgemeinen ist es gut, Wörter wie "handle" oder "process" als Teil von Routinennamen und Klassennamen zu vermeiden, es sei denn, Sie haben es mit (z. B.) Dateihandles oder (z. B.) Unix-Prozessen zu tun. Abstrakte Klassen wissen jedoch oft nicht wirklich, was sie mit etwas anderem anfangen sollen, als es beispielsweise zu verarbeiten. In meiner aktuellen Situation habe ich einen "EmailProcessor", der sich im Posteingang eines Benutzers anmeldet und Nachrichten von diesem verarbeitet. Es ist mir nicht wirklich klar, wie ich diesem einen genaueren Namen geben soll, obwohl ich bemerkt habe, dass die folgende Stilfrage auftritt:
- Es ist besser, abgeleitete Klassen als Clients zu behandeln und die Basisklasse nach dem Teil der von ihr implementierten Funktionalität zu benennen. Gibt ihm mehr Bedeutung, verstößt aber gegen is-a. Zum Beispiel wäre EmailAcquirer ein vernünftiger Name, da er für die abgeleitete Klasse erworben wird, die abgeleitete Klasse jedoch für niemanden.
- Oder einfach nur ein vager Name, denn wer weiß, was die abgeleiteten Klassen tun werden. "Prozessor" ist jedoch immer noch zu allgemein, da er viele relevante Vorgänge ausführt, z. B. das Anmelden und Verwenden von IMAP.
Ein Ausweg aus diesem Dilemma?
Das Problem ist offensichtlicher für abstrakte Methoden, bei denen Sie die Frage "Was macht das?" Nicht wirklich beantworten können. denn die Antwort lautet einfach "was auch immer der Kunde will".
quelle
Antworten:
Das Problem ist nicht der Name, sondern dass Sie zu viel in eine Klasse stecken.
In Ihrer Beispielklasse sind einige Teile sehr konkret (wie die Mails erhalten werden). Andere Teile sind sehr abstrakt (was Sie mit den Mails machen werden).
Besser mit separaten Klassen als mit Vererbung.
Ich schlage vor:
ein abstrakter MessageIterator, der von einem POPMailBoxDownloader untergeordnet wird
Eine andere Klasse, die einen POPMailBoxDownloader besitzt und etwas mit den Nachrichten macht.
quelle
Wenn ich keinen guten Namen für eine Klasse finde, schreibe ich eine Inline-Codedokumentation für die Klasse. Es beschreibt den Zweck der Klasse in einem Duft. Normalerweise kann ich aus dieser Beschreibung einen guten Namen für die Klasse ableiten. Dies ist auch für abstrakte Klassen hilfreich.
Wenn die Beschreibung der Klasse "Anmeldet sich im Posteingang eines Benutzers und verarbeitet Nachrichten von diesem" lautet, würde ich "InboxProcessor" als Klassennamen vorschlagen. Wenn eine abgeleitete Klasse "Anmeldet sich im Posteingang eines Benutzers und verschiebt Spam-E-Mails in einen Spam-Ordner" als Beschreibung hat, würde ich "InboxSpamMover" als Namen wählen.
Ich sehe kein Problem bei der Verwendung von generischen Namen wie "Prozessor", wenn dies den generischen Zweck einer abstrakten Klasse widerspiegelt.
Wenn Sie Probleme haben, den Zweck einer Klasse in ein oder zwei Sätzen zu beschreiben, liegt möglicherweise ein Entwurfsproblem vor. Vielleicht macht die Klasse zu viel und verstößt gegen das Prinzip der Einzelverantwortung . Dies gilt auch für abstrakte Klassen.
quelle
Um Frank Zappa zu paraphrasieren, es ist, was es ist und sollte so genannt werden. Ihr Beispiel geht einfach nicht tief genug in die Art der Verarbeitung ein. Ist es ein
EmailToTroubleTicketProcessor
, einEmailGrammarCorrector
oder einEmailSpamDetector
?Das ist nicht genau richtig; Die Frage, die Sie für etwas Abstraktes nicht beantworten können, lautet: " Wie macht es das, was es macht?" denn das ist implementierungsspezifisch. Wenn eine
EmailSender
Klasse über eineDeliveryStatus deliver(Email e)
Methode verfügt, gibt es einen impliziten Vertrag, wonach eine Implementierung eine E-Mail entgegennimmt, versucht, sie zuzustellen und einen Status über den Verlauf zurückzugeben. Es ist Ihnen egal, ob eine Verbindung zu einem SMTP-Server hergestellt oder ausgedruckt wird, um an eine Brieftaube gebunden zu werden, solange die Implementierung das tut, was versprochen wurde. Abstracts quantifizieren dieses Versprechen nur, damit eine Implementierung sagen kann: "Ja, das mache ich."quelle
void doWhatYouDoWith(Email e)
, können Sie die Klasse dennoch als an bezeichnenEmailDisposer
. Dies ist spezifisch genug, um zu sagen, was sie tut, aber allgemein genug, um festzustellen, wie die Implementierung erfolgt. Obwohl ich denke, dass @KrisVanBael es geschafft hat: Wenn Sie auf etwas so Zweideutiges zurückgegriffen haben, ist möglicherweise zu viel unter einem Dach.Überlegen Sie, warum es schlecht ist, solche Wörter zu verwenden. Sind sie beschreibend? Welche Wörter gibt es, um die Klassen zu beschreiben ? EmailBaseClass? Könnte das aussagekräftiger sein als EmailManager oder ähnliches? Der Schlüssel ist, einen Einblick in die betreffende Klasse zu haben , also finden Sie die richtigen Verben oder Substantive. Behandle deinen Code wie Poesie.
quelle
int age
"ageInteger", nur noch schlimmer, da ich erwarten würde, daraus Klartext-E-Mails, MIME-E-Mails usw. abzuleiten. Keine Notwendigkeit zu beschreiben, was das Wort überhaupt vorausgehtabstract
(dies ist Java). Haben Sie einen besonderen Einblick in den Basisteil dieser Klasse? Und mehr Einsicht löst immer noch nicht das Problem, etwas zu benennen, das eine Is-a-Beziehung kreuzen wird. Ich kann entweder etwas zu Vages oder zu Allgemeines haben. Ich sehe keinen Ausweg, es sei denn, ich hätte es getan mehr Einblick in mehr Einblick.ageInteger
oder so etwas tatsächlich angemessen ist. Die ungarische Notation ist eine abgekürzte Version aus einem Kontext, in dem viel passiert ist. Sicherlich gibt es Zeiten, in denen Sie etwas in der Art und WeiseageNumeric
undageString
im gleichen Umfang benötigen , wobei die Angabe des Typs im Namen die einfachste und klarste Methode zur Unterscheidung ist.systemController
es sich um eine abstrakte Basisklasse oder ein Blatt in einer großen Hierarchie handelt. Natürlich kann dies mit einer IDE behoben werden (wie es bei den meisten Java-Entwicklungen der Fall ist?), Die den Benutzer sofort über den Inhalt und die Struktur der Klasse informieren kann, sodass tatsächlich aufschlussreiche Namen nicht in ähnlicher Weise gerechtfertigt werden können.