Die meisten OO-Sprachen stellen ihren Schnittstellennamen ein Großbuchstaben I voran. Warum macht Java das nicht? Was war der Grund dafür, diese Konvention nicht zu befolgen?
Um zu demonstrieren, was ich meine, hätte ich in Java zwei Möglichkeiten, wenn ich eine Benutzeroberfläche und eine Benutzerimplementierung haben wollte:
- Klasse = Benutzer, Schnittstelle = Benutzerschnittstelle
- Klasse = UserImpl, Schnittstelle = Benutzer
Wo in den meisten Sprachen:
Klasse = Benutzer, Schnittstelle = IUser
Nun könnten Sie argumentieren, dass Sie immer einen aussagekräftigen Namen für die Benutzerimplementierung auswählen könnten und das Problem verschwindet, aber Java drängt auf einen POJO-Ansatz und die meisten IOC-Container verwenden DynamicProxies in großem Umfang. Diese beiden Dinge zusammen bedeuten, dass Sie viele Schnittstellen mit einer einzigen POJO-Implementierung haben.
Ich denke, meine Frage läuft darauf hinaus: "Lohnt es sich, die umfassendere Namenskonvention für Schnittstellen zu befolgen, insbesondere angesichts der Richtung, in die Java Frameworks zu gehen scheinen?"
quelle
NetworkInterface
,DialogInterface
etc.Antworten:
Ich bevorzuge es, kein Präfix für Schnittstellen zu verwenden:
Das Präfix beeinträchtigt die Lesbarkeit.
Die Verwendung von Schnittstellen in Clients ist die beste Standardmethode zum Programmieren. Daher sollten die Namen der Schnittstellen so kurz und angenehm wie möglich sein. Das Implementieren von Klassen sollte hässlicher sein, um von ihrer Verwendung abzuraten.
Beim Wechsel von einer abstrakten Klasse zu einer Schnittstelle impliziert eine Codierungskonvention mit Präfix I das Umbenennen aller Vorkommen der Klasse - nicht gut!
quelle
Gibt es wirklich einen Unterschied zwischen:
und
Wenn es nur um Namenskonventionen geht?
Persönlich bevorzuge ich vorhergehenden NICHT die Schnittstelle ,
I
wie ich will an die Schnittstelle zu Codierung und ich denke , dass in Bezug auf die Namenskonvention wichtiger sein. Wenn Sie die Schnittstelle aufrufen, mussIUser
jeder Verbraucher dieser Klasse wissen, dass es sich um eine Schnittstelle handeltIUser
. Wenn Sie die Klasse aufrufen,UserImpl
wissen nur die Klasse und Ihr DI-Container über dasImpl
Teil Bescheid, und die Verbraucher wissen nur, dass sie mit einem arbeitenUser
.Andererseits war die Zeit, die ich verwenden musste,
Impl
weil sich kein besserer Name anbietet, selten, weil die Implementierung entsprechend der Implementierung benannt wird, weil es dort wichtig ist, zquelle
Es kann mehrere Gründe geben, warum Java die IUser-Konvention im Allgemeinen nicht verwendet.
Ein Teil des objektorientierten Ansatzes besteht darin, dass Sie nicht wissen müssen, ob der Client eine Schnittstelle oder eine Implementierungsklasse verwendet. Selbst wenn List eine Schnittstelle und String eine tatsächliche Klasse ist, wird möglicherweise eine Methode an beide übergeben. Es ist nicht sinnvoll, die Schnittstellen visuell zu unterscheiden.
Im Allgemeinen bevorzugen wir die Verwendung von Schnittstellen im Client-Code (z. B. List gegenüber ArrayList). Es ist also nicht sinnvoll, die Schnittstellen als Ausnahmen hervorzuheben.
Die Java-Namenskonvention bevorzugt längere Namen mit tatsächlichen Bedeutungen gegenüber Präfixen im ungarischen Stil. Damit dieser Code so gut wie möglich lesbar ist: Eine Liste repräsentiert eine Liste, und ein Benutzer repräsentiert einen Benutzer - keinen IUser.
quelle
Es gibt auch eine andere Konvention, die von vielen Open-Source-Projekten einschließlich Spring verwendet wird.
Ich persönlich mag das Präfix "I" nicht aus dem einfachen Grund, dass es eine optionale Konvention ist. Wenn ich dies übernehme, bedeutet IIOPConnection dann eine Schnittstelle für IOPConnection? Was ist, wenn die Klasse nicht das Präfix "I" hat? Weiß ich dann, dass es sich nicht um eine Schnittstelle handelt? Die Antwort hier lautet "Nein", da Konventionen nicht immer befolgt werden und ihre Überwachung mehr Arbeit schafft, als die Konvention selbst spart.
quelle
Wie in einem anderen Poster bereits erwähnt, ist es normalerweise vorzuziehen, dass Schnittstellen Funktionen und keine Typen definieren. Ich würde dazu neigen, so etwas wie einen "Benutzer" nicht zu "implementieren", und deshalb ist "IUser" in der hier beschriebenen Weise oft nicht wirklich notwendig. Ich sehe Klassen oft als Substantive und Schnittstellen als Adjektive:
Manchmal macht ein Adjektiv keinen Sinn, aber ich würde im Allgemeinen immer noch Schnittstellen verwenden, um Verhalten, Aktionen, Funktionen, Eigenschaften usw. zu modellieren, nicht Typen.
Wenn Sie wirklich nur einen Benutzer erstellen und ihn als Benutzer bezeichnen würden, was bringt es dann, auch eine IUser-Oberfläche zu haben? Und wenn Sie einige verschiedene Benutzertypen haben, die eine gemeinsame Schnittstelle implementieren müssen, was erspart Ihnen das Anhängen eines "I" an die Schnittstelle bei der Auswahl der Namen der Implementierungen?
Ich denke, ein realistischeres Beispiel wäre, dass einige Benutzertypen sich bei einer bestimmten API anmelden müssen. Wir könnten eine Anmeldeschnittstelle definieren und dann eine übergeordnete Klasse "Benutzer" mit den Klassen SuperUser, DefaultUser, AdminUser, AdministrativeContact usw. haben, von denen einige die Anmeldeschnittstelle (Anmeldefähig?) Nach Bedarf implementieren oder nicht.
quelle
indefinite transitive verbs
8 ^ PBob Lee sagte einmal in einer Präsentation:
Sie beginnen also mit einer Implementierung, dh ohne Schnittstelle. Später entscheiden Sie, dass hier eine Schnittstelle erforderlich ist, und konvertieren Ihre Klasse in eine Schnittstelle.
dann wird klar: Ihre ursprüngliche Klasse hieß Benutzer. Ihre Schnittstelle heißt jetzt Benutzer. Vielleicht haben Sie ein UserProdImpl und ein UserTestImpl. Wenn Sie Ihre Anwendung gut entworfen haben, bleibt jede Klasse (mit Ausnahme derjenigen, die den Benutzer instanziieren) unverändert und merkt nicht, dass sie plötzlich eine Schnittstelle erhalten.
so wird es klar -> Schnittstelle Benutzerimplementierung UserImpl.
quelle
In C # ist es
Java würde sagen
Aus diesem Grund denke ich, dass Konventionen in Java für Schnittstellen nicht annähernd so wichtig sind, da es einen expliziten Unterschied zwischen Vererbung und Schnittstellenimplementierung gibt. Ich würde sagen, wählen Sie einfach eine beliebige Namenskonvention, solange Sie konsistent sind und etwas verwenden, um den Leuten zu zeigen, dass dies Schnittstellen sind. Ich habe seit ein paar Jahren kein Java mehr gemacht, aber alle Schnittstellen befinden sich nur in einem eigenen Verzeichnis, und das war die Konvention. Hatte nie wirklich Probleme damit.
quelle
Nach meiner Erfahrung gilt die "I" -Konvention für Schnittstellen, die einen Vertrag für eine Klasse bereitstellen sollen, insbesondere wenn die Schnittstelle selbst kein abstrakter Begriff der Klasse ist.
In Ihrem Fall würde ich beispielsweise nur erwarten,
IUser
ob der einzige Benutzer, den Sie jemals haben möchten, der istUser
. Wenn Sie verschiedene Arten von Benutzern haben planen -NoviceUser
,ExpertUser
usw. - ich würde erwarten , dass eine sehenUser
Schnittstelle (und vielleicht eineAbstractUser
Klasse, die implementiert einige gemeinsame Funktionalität, wieget/setName()
).Ich würde auch Schnittstellen erwarten , die Fähigkeiten definieren -
Comparable
,Iterable
usw. - zu so genannt zu werden, und nicht wieIComparable
oderIIterable
.quelle
Nach guten OO-Prinzipien sollte Ihr Code (soweit praktikabel / möglich) eher von Abstraktionen als von konkreten Klassen abhängen. Zum Beispiel ist es im Allgemeinen besser, eine Methode wie diese zu schreiben:
als das:
Wenn Sie dieser Idee folgen, ist Ihr Code meiner Meinung nach besser lesbar, wenn Sie Schnittstellennamen wie "Benutzer" und "Bankkonto" (z. B.) anstelle von "IUser", "Benutzerschnittstelle" oder anderen Variationen angeben.
Die einzigen Codebits, die sich um die tatsächlichen konkreten Klassen kümmern sollten, sind die Stellen, an denen die konkreten Klassen erstellt werden. Alles andere sollte über die Schnittstellen geschrieben werden.
Wenn Sie dies tun, sollten die "hässlichen" konkreten Klassennamen wie "UserImpl" sicher vor dem Rest des Codes verborgen sein, der fröhlich mit den "netten" Schnittstellennamen fortfahren kann.
quelle
= v = Das Präfix "I" wird auch im Wicket-Framework verwendet, an das ich mich schnell gewöhnt habe. Im Allgemeinen begrüße ich jede Konvention, die umständliche Java-Klassennamen verkürzt. Es ist jedoch problematisch, dass in den Verzeichnissen und im Javadoc alles unter "I" alphabetisch sortiert ist.
Die Wicket-Codierungspraxis ähnelt der von Swing, da viele Steuerungs- / Widget-Instanzen als anonyme innere Klassen mit Inline-Methodendeklarationen erstellt werden. Ärgerlicherweise unterscheidet es sich um 180 ° von Swing darin, dass Swing ein Präfix ("J") für die implementierenden Klassen verwendet.
Das Suffix "Impl" ist eine knappe Abkürzung und lässt sich nicht gut internationalisieren. Wenn wir nur wenigstens mit "Imp" gegangen wären, wäre es niedlicher (und kürzer). "Impl" wird für IOC verwendet, insbesondere für Spring, also bleiben wir vorerst dabei. Es wird jedoch ein bisschen schizo nach 3 verschiedenen Konventionen in drei verschiedenen Teilen einer Codebasis.
quelle
Ist dies eine umfassendere Namenskonvention im eigentlichen Sinne? Ich bin eher auf der C ++ - Seite und nicht wirklich auf Java und Nachkommen. Wie viele Sprachgemeinschaften verwenden die I-Konvention?
Wenn Sie hier eine sprachunabhängige Namenskonvention für Shop-Standards haben, verwenden Sie diese. Wenn nicht, befolgen Sie die Namenskonvention für Sprachen.
quelle