Sollte ich meinen abstrakten Klassen ein "Abstract" -Präfix hinzufügen? [geschlossen]

20

Angenommen, ich habe eine abstrakte Klasse mit dem Namen Task.

Gibt es einen Standard oder eine Konvention, nach der ich ihn AbstractTaskstattdessen benennen sollte ?

Juan
quelle
Hier aufgeführte Namenskonventionen: oracle.com/technetwork/java/codeconventions-135099.html schlagen Nein vor, obwohl dieser Link besagt, dass Sie dies könnten und es keine schreckliche Sache wäre, wenn Sie dies tun würden.
FrustratedWithFormsDesigner
In C # lautet die Standardkonvention, Suffixe mit '* Base' zu setzen.
Den

Antworten:

26

Gemäß Blochs Effective Java (Punkt 18) ist das Abstract-Präfix eine Konvention, die in einem speziellen Fall verwendet wird.

Sie können die Vorzüge von Schnittstellen und abstrakten Klassen kombinieren, indem Sie eine abstrakte Skelettimplementierungsklasse für jede nicht-triviale Schnittstelle bereitstellen, die Sie exportieren. ... Konventionell werden Skelettimplementierungen als AbstractInterface bezeichnet, wobei Interface der Name der von ihnen implementierten Schnittstelle ist.

Bloch weist aber auch darauf hin, dass der Name SkeletalInterface Sinn gemacht hätte, schließt aber daraus

Die abstrakte Konvention ist nun fest etabliert.

Wie andere Antworten gezeigt haben, gibt es im Allgemeinen keinen Grund, diese Namenskonvention auf alle abstrakten Klassen anzuwenden.

Narbenkühlschrank
quelle
15

Es gibt keine Konvention. Es geht darum, was Ihnen als Entwickler dabei helfen wird, Code schneller und besser zu erstellen und anderen zu helfen, Ihren Code zu verstehen.

Fragen Sie die Leute, die den Code sehen und warten werden. Was würden sie lieber sehen? Was wird es ihnen leichter machen? Nennen Sie es dann basierend auf dem, was sie möchten.

In einem anderen Hinweis, Code-Konventionen für die Java-Programmiersprache: 9. Namenskonventionen erfordern keine:

Klassennamen sollten Substantive sein, wobei der erste Buchstabe jedes internen Wortes groß geschrieben wird. Versuchen Sie, Ihre Klassennamen einfach und aussagekräftig zu halten. Verwenden Sie ganze Wörter - vermeiden Sie Akronyme und Abkürzungen (es sei denn, die Abkürzung wird viel häufiger verwendet als die Langform wie URL oder HTML).

Dynamisch
quelle
13

Intellisense wird mir trivialerweise mitteilen, ob es abstrakt ist, also verletzen Sie hier nur DRY.

DeadMG
quelle
21
-1 Das Hinzufügen abstracteines Klassennamens verletzt DRY nicht und nicht jeder verwendet Intelligenz. Was tun Sie beispielsweise, wenn Sie den Code auf einer Webseite lesen oder wenn er Teil eines Patches ist, den Sie in einem Nur-Text-Editor oder einem externen Diff-Tool anzeigen?
Bryan Oakley
10
@ Bryan: Natürlich verletzt es DRY. abstract class AbstractName? Hat eindeutig zweimal "abstrakt". Und wenn Sie nicht Intellisense verwenden, ist dies Ihr Problem. Alle anderen verwenden vernünftige Tools, um Code anzuzeigen.
DeadMG
13
"Jeder"? Die meisten Leute, die ich kenne, verwenden Emacs und Vi, einige verwenden Eclipse. Etwas zu sagen ist "Ihr Problem" ist nicht genau die Definition von Teamwork. Mein schlecht gemachter Punkt war, man kann nicht einfach eine Pauschalregel festlegen und sagen, dass es so gemacht wird. Unterschiedliche Teams haben unterschiedliche Anforderungen, und nicht jeder braucht Unterstützung beim Thema Intellisense. Außerdem gibt es, wie gesagt, viele Fälle, in denen Sie Code in einem anderen Tool als Ihrem primären Editor oder Ihrer IDE betrachten.
Bryan Oakley
1
+1 verstößt definitiv gegen DRY. Sich auf Intellisense zu verlassen, ist ein bisschen stark, aber jeder, der die Basisklasse verwendet, sollte zumindest nachsehen, was er als Teil von SOLID erweitert.
Gary Rowe
8
@BryanOakley warum nicht auch öffentlich und endgültig? Ein Klassenname würde dann wie folgt aussehen: PublicAbstractPersonThatImplementsInterfaceHuman. Hmm, nicht ganz sicher, ob das gut ist. Aber ich stimme zu, es gibt nichts wie eine universelle Konvention - verwenden Sie, was auch immer die kollektive Produktivität des Teams steigert.
Apoorv Khurasia
9

Dies ist etwas eine Frage der Präferenz (aber grenzwertig schlechte Praxis), aber die meisten Leute mögen es nicht, einen Teil der Qualifikanten im Namen der Klasse zu sehen.

Die meisten IDEs stellen diese Informationen sowieso problemlos zur Verfügung, sodass es nicht erforderlich ist, sie in den Namen einzufügen, und es ist sauberer, sie einfach wegzulassen. Es erinnert an die ungarische Notation für Variablennamen, und das wird heutzutage sicherlich als schlechte Form angesehen. Ich empfehle es einfach anzurufen Task.

Oleksi
quelle
9

In .NET wird häufig die Verwendung von "Base" als Suffix zur Bezeichnung einer abstrakten Basisklasse verwendet. Ich würde auf die anderen Antworten zurückgreifen, ob dies in Java üblich ist.

KeithS
quelle
1
+1 für die Suffixe "Base" und "Impl". Sie machen einen strukturellen Punkt (eine abstrakte Klasse wird die Basis für etwas sein).
Vski
7
@vski: Nein, da stimme ich überhaupt nicht zu: Sie sind ein unnützer Schmerz im Hintern. Es ist im Allgemeinen völlig in Ordnung, Ihre Schnittstelle oder Basisklasse mit einem generischen Namen zu bezeichnen, der die Schnittstelle beschreibt, und Ihre konkrete Implementierung mit genaueren Namen.
Haylem
3
Ich neige dazu, ... Base für eine Basisklasse hinter einer Schnittstelle zu verwenden. Der gute Name wird bereits von der Schnittstelle verwendet, und die Basisklasse wird vom Clientcode ohnehin nicht verwendet.
Starblue
1
@ Haylem Viele Java-Entwurfsmuster verwenden Schnittstellen mit nur einer erwarteten Implementierung. Impl ist in diesen Fällen ein sehr nützliches Suffix.
Funkybro
Bezüglich der Verwendung von Impl siehe Default vs Impl - halte dich von Impl fern! Die Verwendung von Base als Suffix (z. B. TaskBase) impliziert, dass eine Basisklasse eher ein Muster als ein Sprachkonstrukt ist.
Gary Rowe
8

Meiner Meinung nach sollte der Name einer Entität keine Informationen über ihre Typstruktur vermitteln, sondern über ihre Semantik. Es ist daher nicht sinnvoll, Ihre Klasse als "AbstractSomething" zu definieren, wenn die Abstraktion nicht Teil ihres Laufzeitziels ist. Dass es sich um eine abstrakte Basisklasse handelt, ist für den Programmierer sichtbar und muss sich nicht im Namen widerspiegeln.

Wenn es jedoch perfekt ist, eine Implementierung einer abstrakten Factory als AbstractFactory zu bezeichnen, hängt dies mit der Absicht der Klasse zusammen.

Bevorzugen Sie im Allgemeinen Namenskonventionen, mit denen Sie die meisten Informationen über das Ziel Ihrer Klasse übermitteln können.

Ebenso fern bleiben von SomethingImpl. Es ist uns egal, dass es sich um eine Implementierung und nicht um eine Basisklasse handelt. Wenn Ihre Klassenhierarchie ordnungsgemäß für die Vererbung ausgelegt ist, kann jemand davon erben. Sicherlich würde es keinen Wert geben, wenn sie mehr "Impl" -Suffixe oder andere Artefakte hinzufügen würden. Es ist auch nicht sinnvoll, ein Suffix "Schnittstelle" oder ein Präfix "I" hinzuzufügen.

Erwägen:

IVehicle <-- IMotoredVehicle <-- AbstractCar <-- CarImpl

Im Gegensatz zu:

Vehicle <-- MotoredVehicle <-- Car <-- DefaultCar
                                   <-- Ferrari
                                   <-- Trabi

Ich bevorzuge das letztere bei weitem.


Dies ähnelt in gewisser Hinsicht dem offensichtlichen Missbrauch der Ungarischen Notation , die letztere ihren schlechten Ruf gab , da die Leute fälschlicherweise damit begannen, sie dahingehend zu interpretieren, dass Entwickler ihren Variablen einen Indikator des Variablentyps voranstellen müssen. Obwohl dies manchmal nützlich sein kann (meistens, wenn Sie die Definition des Typs nicht genau nachschlagen können), ist es meistens nutzlos. Simonyis ursprüngliche Idee mit der ungarischen Notation war es, sie als Mnemonik zu verwenden, um den Entwickler an die Fähigkeiten der Entität zu erinnern, nicht an ihren Typ.

Haylem
quelle
3

Eine gute Faustregel ist, keine Eigenschaften in einen Namen aufzunehmen, die sich aus der Syntax ergeben. Da Sie in Java eine abstrakte Klasse mit dem passenden abstractSchlüsselwort kennzeichnen müssen , würde ich es nicht in den Namen aufnehmen. In C ++ ist der Fall zum Beispiel nicht so eindeutig, aber zumindest der Compiler wird Ihnen mitteilen, wenn Sie eine abstrakte Klasse falsch verwendet haben. In so etwas wie Python ist es keine schlechte Idee, eine abstrakte Klasse explizit als solche zu bezeichnen.

Die übliche Ausnahme von der Regel ist, wenn der Name nicht eindeutig ist. Wenn es aus irgendeinem Grund eine konkrete Unterklasse gibt Task(in anderen Beispielen mag dies sinnvoller sein, aber was auch immer), verwenden Sie diese AbstractTask.

Benjamin Kloster
quelle
... oder ein Interface wie Listund die AbstractListKlasse (die es implementiert).
3
protected abstract SomeClass { }

Dies sagt mir, dass dies eine abstrakte Klasse ist. Das Hinzufügen eines Präfixes ist eine Tautologie und ein Anti-Pattern und in den meisten Fällen nicht angebracht. Sehen Sie sich den Link an, in dem es beispielsweise darum geht package local, eine Ausnahme zu sein.

In den meisten Fällen AbstractKlassen sollten nicht Teil einer öffentlich zugänglichen API sein, wenn es wirklich ein guter Grund ist da und ein guter Grund sein sollte , sollte eine offensichtlich gute anderen Namen als bieten AbstractSomeClass.

In den meisten Fällen, in denen Sie keinen aussagekräftigeren Namen finden können, müssen Sie wahrscheinlich eine Neugestaltung vornehmen.


quelle
0

Meine fünf Cent, wahrscheinlich haben Sie Implementierungen dieser abstrakten Klasse und sie werden 'SomeSpecificTask', 'TaskWithBubbles', 'StrangeTask' usw. heißen. Es wird also keinen Namenskonflikt zwischen Ihrer abstrakten 'Task' und ihnen geben.

Darüber hinaus handelt es sich bei "abstrakten" Wörtern um Sprachsyntax und nicht um Geschäftsdomänenentitäten. Daher würde ich es vorziehen, sie nicht als Teil des Namens zu verwenden.

Auf der anderen Seite habe ich in einer Antwort hier einen Auszug aus J.Bloch Effective Java gesehen, der besagt, dass die Verwendung von 'abstract' als Teil eines Namens eine etablierte Praxis ist. Es kann so sein. Aber in offiziellen Java-Code-Konventionen gibt es sowieso nichts darüber.


quelle
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>- man kann nicht Listals Name für die AbstractListKlasse verwenden, da dies der Name der Schnittstelle ist. Es ist eine etablierte Praxis und Teil des offiziellen Java-Codes, der verwendet wird, wenn etwas, das die Schnittstelle implementiert, eine abstrakte Klasse erweitern kann oder nicht (die auch (einige) der Schnittstelle implementiert).
-1

Wenn Sie in einem Team arbeiten, muss das gesamte Team entscheiden, ob Sie abstrakten Klassen "Abstract" voranstellen sollen.

Wenn Sie alleine arbeiten, liegt es ganz bei Ihnen, nicht bei mir oder sonst jemandem auf dieser Site.

CodeART
quelle
-2

Ich bin kein Java-Entwickler (INAJD?) Und kenne die Standard-Nomenklatur für solche Dinge nicht, aber ich denke, das Taskhört sich abstrakt genug an, um so wie es ist für sich zu stehen.

Jesse C. Slicer
quelle
RE: Basis - Suffix: stackoverflow.com/a/429494/1782
juan
-2

Was ist, wenn Sie eine abstrakte AbstractSyntaxTreeKlasse schreiben möchten ? Oder vielleicht nur eine Zusammenfassung SyntaxTree?

Es ist nicht konventionell und kann Menschen leicht verwirren.

tskuzzy
quelle
-2

Ich hab's gemacht. Ich habe meiner abstrakten Klasse 'AbstractOperation' das Präfix 'Abstract' hinzugefügt. Der Grund, warum ich das getan habe, war, dass es ein anderes Paket gab, das eine nicht abstrakte Klasse namens Operation hatte, und das meinem Team und den später übernommenen Programmierern half, Verwechslungen zwischen den beiden zu vermeiden.

Abhishek Oza
quelle