wake-up-neo.com

Benennung der Schnittstelle in Java

Die meisten OO Sprachen stellen ihren Schnittstellennamen ein Großbuchstaben I voran. Warum tun Java nicht? Was war der Grund dafür, diese Konvention nicht zu befolgen?

Um zu demonstrieren, was ich meine, wenn ich eine Benutzeroberfläche und eine Benutzerimplementierung haben möchte, hätte ich zwei Möglichkeiten in Java:

  1. Klasse = Benutzer, Schnittstelle = Benutzeroberfläche
  2. Klasse = UserImpl, Schnittstelle = User

Wo in den meisten Sprachen:

Klasse = Benutzer, Schnittstelle = Benutzer

Nun könnten Sie argumentieren, dass Sie immer einen aussagekräftigsten Namen für die Benutzerimplementierung wählen könnten und das Problem damit nicht mehr besteht, aber Java pusht einen POJO-Ansatz, und die meisten IOC= Container verwenden DynamicProxies ausgiebig. Diese Zwei Dinge zusammen bedeuten, dass Sie viele Schnittstellen mit einer einzigen POJO-Implementierung haben.

Ich schätze, meine Frage läuft auf Folgendes hinaus: "Lohnt es sich, die allgemeinere Namenskonvention für die Benutzeroberfläche zu befolgen, insbesondere in Anbetracht dessen, wohin Java Frameworks scheinen zu gehen?"

309
Allain Lalonde

Ich bevorzuge es, kein Präfix für Schnittstellen zu verwenden:

  • Das Präfix schadet der Lesbarkeit.

  • Die Verwendung von Schnittstellen in Clients ist die beste Standardmethode für die Programmierung. Daher sollten die Namen der Schnittstellen so kurz und angenehm wie möglich sein. Das Implementieren von Klassen sollte hässlicher sein, um deren Verwendung zu verhindern.

  • Beim Wechsel von einer abstrakten Klasse zu einer Schnittstelle impliziert eine Codierungskonvention mit Präfix, dass alle Vorkommen der Klasse umbenannt werden - nicht gut!

312
starblue

Gibt es wirklich einen Unterschied zwischen:

class User implements IUser

und

class UserImpl implements User

wenn wir nur über Namenskonventionen sprechen?

Persönlich bevorzuge ich es, der Schnittstelle NICHT I voranzustellen, da ich die Schnittstelle codieren möchte und dass im Hinblick auf die Namenskonvention für wichtiger halte. Wenn Sie das Interface IUser aufrufen, muss jeder Consumer dieser Klasse sein IUser kennen. Wenn Sie die Klasse UserImpl aufrufen, wissen nur die Klasse und Ihr DI-Container über den Teil Impl Bescheid, und die Konsumenten wissen nur, dass sie mit einem User arbeiten.

Andererseits waren die Zeiten, in denen ich gezwungen war, Impl zu verwenden, weil sich kein besserer Name anbietet, sehr kurz, da die Implementierung den Namen entsprechend für die Implementierung erhält, weil dort ist es wichtig, z.

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
108
tddmonkey

Es kann mehrere Gründe geben Java verwendet im Allgemeinen nicht die IUser-Konvention.

  1. 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, kann eine Methode an beide übergeben werden. Eine visuelle Unterscheidung der Schnittstellen ist daher nicht sinnvoll.

  2. Im Allgemeinen bevorzugen wir die Verwendung von Schnittstellen im Client-Code (bevorzugen beispielsweise List gegenüber ArrayList). Daher ist es nicht sinnvoll, die Schnittstellen als Ausnahmen hervorzuheben.

  3. Die Java Namenskonvention bevorzugt längere Namen mit einer tatsächlichen Bedeutung gegenüber Präfixen im ungarischen Stil. Damit der Code so gut wie möglich lesbar ist: Eine Liste steht für eine Liste, und ein Benutzer steht für einen Benutzer - nicht für eine IUser.

75
Avi

Es gibt auch eine andere Konvention, die von vielen Open Source-Projekten, einschließlich Spring, verwendet wird.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

Ich persönlich mag das Präfix "I" aus dem einfachen Grund nicht, 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 lautet "Nein", da Konventionen nicht immer befolgt werden und ihre Überwachung mehr Arbeit schafft, als die Konvention selbst spart.

70
ng.

Wie in einem anderen Poster bereits erwähnt, ist es in der Regel vorzuziehen, dass Schnittstellen Funktionen definieren, nicht Typen. Ich würde eher nicht so etwas wie einen "Benutzer" "implementieren", und deshalb ist "IUser" in der hier beschriebenen Weise oft nicht wirklich notwendig. Ich sehe Klassen oft als Substantive und Schnittstellen als Adjektive:

class Number implements Comparable{...}  
class MyThread implements Runnable{...}
class SessionData implements Serializable{....}

Manchmal macht ein Adjektiv keinen Sinn, aber ich würde im Allgemeinen immer noch Schnittstellen verwenden, um Verhalten, Aktionen, Fähigkeiten, Eigenschaften usw. zu modellieren, nicht Typen.

Außerdem: 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 Arten von Benutzern in der Lage sein müssen, sich bei einer bestimmten API anzumelden. Wir könnten eine Login-Schnittstelle definieren und dann eine übergeordnete Klasse "User" mit den Klassen SuperUser, DefaultUser, AdminUser, AdministrativeContact usw. haben, von denen einige die Login-Schnittstelle (Loginable?) Nach Bedarf implementieren oder nicht implementieren.

45
nairbv

Bob Lee sagte einmal in einer Präsentation:

was ist der Sinn einer Schnittstelle, wenn Sie nur eine Implementierung haben.

sie beginnen also mit einer Implementierung, d. h. ohne Schnittstelle. später entscheiden Sie, ob hier eine Schnittstelle erforderlich ist, und konvertieren Ihre Klasse in eine Schnittstelle.

dann wird klar: Ihre ursprüngliche Klasse hieß User. Ihre Schnittstelle heißt jetzt Benutzer. Vielleicht haben Sie einen UserProdImpl und einen 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 über eine Schnittstelle geleitet werden.

so wird es klar -> Benutzeroberfläche Benutzerimplementierung UserImpl.

36

In C # ist es

public class AdminForumUser : UserBase, IUser

Java würde sagen

public class AdminForumUser extends User implements ForumUserInterface

Aus diesem Grund denke ich, dass Konventionen in Java für Interfaces nicht so wichtig sind, da es einen expliziten Unterschied zwischen Vererbung und Implementierung von Interfaces gibt. Ich würde sagen, wählen Sie einfach eine beliebige Namenskonvention wie, solange Sie konsistent sind und etwas verwenden, um den Leuten zu zeigen, dass dies Schnittstellen sind. Habe in ein paar Jahren noch nicht Java, aber alle Schnittstellen würden sich nur in ihrem eigenen Verzeichnis befinden, und Das war die Konvention, hatte nie wirklich Probleme damit.

24
Matt Briggs

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 zu sehen, wenn der einzige Benutzer, den Sie jemals haben möchten, User ist. Wenn Sie verschiedene Arten von Benutzern haben möchten - NoviceUser, ExpertUser usw. -, würde ich eine User -Oberfläche (und möglicherweise eine AbstractUser -Oberfläche) erwarten ] _ Klasse, die einige allgemeine Funktionen implementiert, z. B. get/setName()).

Ich würde auch erwarten, dass Schnittstellen, die Fähigkeiten definieren - Comparable, Iterable usw. - so benannt werden und nicht wie IComparable oder IIterable.

6
David Koelle

Nach guten OO) Grundsätzen sollte Ihr Code (soweit praktikabel/möglich) eher von Abstraktionen als von konkreten Klassen abhängen. Beispielsweise ist es im Allgemeinen besser, eine Methode wie die folgende zu schreiben:

public void doSomething(Collection someStuff) {
    ...
}

als das:

public void doSomething(Vector someStuff) {
    ...
}

Wenn Sie dieser Idee folgen, dann behaupte ich, dass Ihr Code besser lesbar ist, wenn Sie Schnittstellen-Namen wie "User" und "BankAccount" (zum Beispiel) anstelle von "IUser", "UserInterface" oder anderen Variationen vergeben.

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, was unter Verwendung der "Nice" -Schnittstellennamen fröhlich weitergehen kann.

5
KarstenF

= v = Das Präfix "I" wird auch im Wicket-Framework verwendet, wo ich mich schnell daran gewöhnt habe. Im Allgemeinen begrüße ich jede Konvention, die umständliche Java Klassennamen verkürzt. Es ist jedoch ein Ärger, dass in den Verzeichnissen und im Javadoc alles unter "I" alphabetisiert ist.

Die Wicket-Codierungspraxis ähnelt der von Swing, da viele Steuerelement-/Widget-Instanzen als anonyme innere Klassen mit Inline-Methodendeklarationen erstellt werden. Es ist ärgerlich, dass Swing ein Präfix ("J") für die implementierenden Klassen verwendet.

Das Suffix "Impl" ist eine räudige 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. Es wird ein bisschen schizo, wenn man drei verschiedene Konventionen in drei verschiedenen Teilen einer Codebasis befolgt.

2
Jym Dyer

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 Shop-Standard-Namenskonvention haben, verwenden Sie diese. Wenn nicht, befolgen Sie die Namenskonvention.

0
David Thornley