370 Stimmen

Schnittstellennamen in Java

Die meisten OO-Sprachen präfixieren ihre Schnittstellennamen mit einem großen I, warum macht Java das nicht? Was war der Grund, diese Konvention nicht zu befolgen?

Um zu verdeutlichen, was ich meine: Wenn ich eine Benutzerschnittstelle und eine Benutzerimplementierung haben möchte, hätte ich in Java zwei Möglichkeiten:

  1. Klasse = Benutzer, Schnittstelle = BenutzerSchnittstelle
  2. Klasse = BenutzerImpl, Schnittstelle = Benutzer

Während in den meisten Sprachen:

Klasse = Benutzer, Schnittstelle = IBenutzer

Jetzt könnte man argumentieren, dass man immer einen aussagekräftigeren Namen für die Benutzerimplementierung wählen könnte und das Problem verschwindet, aber Java drängt auf einen POJO-Ansatz und die meisten IOC-Container verwenden umfangreich DynamicProxies. Diese beiden Dinge zusammen bedeuten, dass Sie viele Schnittstellen mit einer einzigen POJO-Implementierung haben werden.

Also, meine Frage kommt letztlich darauf hinaus: "Ist es sinnvoll, der breiteren Schnittstellennamenskonvention zu folgen, insbesondere angesichts der Richtung, in die Java-Frameworks zu gehen scheinen?"

70 Stimmen

"Wo in den meisten Sprachen"? Welche Sprachen außer den .Net-Sprachen?

0 Stimmen

Nicht nur die .NET-Sprachen; C++ ist eine verwendbare .NET-Sprache und hat nicht per se Schnittstellen (abstrakte Basisklassen können mit etwas Implementierung geliefert werden). Kommt diese Frage letztendlich darauf an, "Warum ist Java nicht wie C#?"?

0 Stimmen

Nein, die Frage basiert auf Java, aber es handelt sich wirklich um eine Frage zu Namenskonventionen für Schnittstellen und warum einige Sprachen sich entscheiden, Dinge auf bestimmte Weisen zu tun.

367voto

starblue Punkte 53167

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 der Standard und beste Weg zum Programmieren, daher sollten Schnittstellennamen so kurz und angenehm wie möglich sein. Implementierungsklassen sollten hässlicher sein, um ihre Verwendung zu entmutigen.

  • Beim Wechsel von einer abstrakten Klasse zu einer Schnittstelle impliziert eine Codierungsrichtlinie mit dem Präfix I die Umbenennung aller Vorkommen der Klasse --- nicht gut!

13 Stimmen

Völlig einverstanden. Eine weitere Taste zum Tippen, wenn Sie die automatische Vervollständigung verwenden. Viele Dateien beginnen mit einem I.

90 Stimmen

Jede anständige IDE macht das Ändern des Codes auf die von Ihnen beschriebene Weise einfach. Außerdem müssen Ihre Kunden meiner Meinung nach ohnehin neu kompilieren, wenn sie von einer abstrakten Klasse zu einem Interface wechseln.

67 Stimmen

Super spät hier, aber: Es spielt überhaupt keine Rolle, ob eine IDE das Ändern des Namens von etwas einfach macht. Code, der eine Instanz eines bestimmten Typs verwendet, sollte niemals darauf achten, ob dieser Typ ein Interface oder eine Klasse ist oder was auch immer. Daher ist es sinnlos und schädlich für das Verständnis, solch ein Detail im Namen des Typs zu offenbaren. Der Typ und der Vertrag, den er offenbart, sind das Wichtige!

136voto

tddmonkey Punkte 19992

Gibt es wirklich einen Unterschied zwischen:

class User implements IUser

und

class UserImpl implements User

wenn es nur um Namenskonventionen geht?

Persönlich bevorzuge ich es, das Interface NICHT mit I zu versehen, da ich nach dem Interface codieren möchte und das für mich in Bezug auf die Namenskonvention wichtiger ist. Wenn Sie das Interface IUser nennen, muss jeder Verbraucher dieser Klasse wissen, dass es sich um einen IUser handelt. Wenn Sie die Klasse UserImpl nennen, wissen nur die Klasse und Ihr DI-Container über den Impl-Teil Bescheid und die Verbraucher 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 ergab, selten, weil die Implementierung entsprechend benannt wird, da dies wichtig ist, z.B.

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO

0 Stimmen

Ich denke, du möchtest wissen, dass es sich um ein DAO handelt, da dies die allgemeine Funktionalität beschreibt, ohne die Klasse öffnen zu müssen. Wenn ich durch die Klassendateien in einem Projekt suche, ist es einfach, alle DAOs zu sehen, indem ich nach *DAO suche.

6 Stimmen

DAO ist ein bekanntes Muster für den Datenbankzugriff, daher macht es es einfach zu wissen, was die Klasse macht, wenn das Muster im Namen enthalten ist. P.S. Es wäre besser, die Kamelnotation streng zu befolgen ("AccountDao"), wie in mina.apache.org/changes-between-2x-and-1x.html

4 Stimmen

@Marker, es ist nicht so, als hätte man ein I, um ein Interface anzugeben. DAO sagt Ihnen, dass die Klasse oder das Interface ein Objekt zum Zugriff auf Kontodaten ist, was das Objekt tut. Ein I zu haben, sagt Ihnen, dass es sich um ein Interface handelt, das nichts mit dem Objekt selbst zu tun hat, sondern mit der Semantik der Sprache.

83voto

Avi Punkte 19623

Es gibt möglicherweise mehrere Gründe, warum Java im Allgemeinen nicht die IUser-Konvention verwendet.

  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 ist und String eine tatsächliche Klasse ist, könnte einer Methode beide übergeben werden - es ergibt keinen Sinn, die Schnittstellen visuell zu unterscheiden.

  2. Im Allgemeinen bevorzugen wir die Verwendung von Schnittstellen im Client-Code (zum Beispiel List anstelle von ArrayList). Es ergibt also keinen Sinn, die Schnittstellen als Ausnahmen hervorzuheben.

  3. Die Java-Namenskonvention bevorzugt längere Namen mit tatsächlicher Bedeutung gegenüber ungarischen Präfixen. So wird der Code so lesbar wie möglich sein: Eine List repräsentiert eine Liste, und ein User repräsentiert einen Benutzer - nicht einen IUser.

82voto

ng. Punkte 6919

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

Schnittstelle Benutzer {
}

Klasse DefaultBenutzer implementiert Benutzer {
}

Klasse AnotherClassOfBenutzer implementiert Benutzer {
}

Persönlich mag ich das "I"-Präfix aus dem einfachen Grund nicht, dass es eine optionale Konvention ist. Wenn ich das übernehme, bedeutet dann IIOPConnection eine Schnittstelle für IOPConnection? Was ist, wenn die Klasse kein "I"-Präfix hat, weiß ich dann, dass es keine Schnittstelle ist? Die Antwort hier ist nein, denn Konventionen werden nicht immer befolgt, und deren Durchsetzung wird mehr Arbeit schaffen, als die Konvention selbst einspart.

0 Stimmen

Ich mag das, da es auch hilft, Sie in den Modus der Verwendung von Schnittstellen für externe Abhängigkeiten zu bringen, anstatt die Klassen zu koppeln.

55voto

nairbv Punkte 3686

Wie ein anderer Poster sagte, ist es in der Regel vorzuziehen, dass Schnittstellen Fähigkeiten und nicht Typen definieren. Ich würde tendenziell nicht etwas wie einen "User" "implementieren", und deshalb ist ein "IUser" oft nicht wirklich notwendig, wie hier beschrieben. Oft sehe ich Klassen als Nomen und Schnittstellen als Adjektive:

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

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

Außerdem, wenn Sie wirklich nur einen Benutzer erstellen und ihn Benutzer nennen würden, was wäre dann der Sinn daran, auch eine IUser-Schnittstelle zu haben? Und wenn Sie verschiedene Arten von Benutzern haben, die eine gemeinsame Schnittstelle implementieren müssen, was bringt es Ihnen, ein "I" an die Schnittstelle anzuhängen, um Namen für die Implementierungen zu wählen?

Ich denke, ein realistischeres Beispiel wäre, dass einige Arten von Benutzern sich bei einer bestimmten API anmelden können müssen. Wir könnten eine Anmelde-Schnittstelle definieren und dann eine Elternklasse "Benutzer" mit Unterklassen wie Superbenutzer, Standardbenutzer, Admin-Benutzer, Administrativer Kontakt usw. haben, von denen einige die Anmelde-Schnittstelle je nach Bedarf implementieren oder nicht.

0 Stimmen

Ich glaube, die Beispiele, die Sie geben, um "Interfaces als Adjektive" zu unterstützen, sind verzerrt, da diese Interfaces eher wie Mix-Ins (oder Traits) gedacht sind. Interfaces sind also gut für Adjektive und Nomen - aber wahrscheinlich nicht für unbestimmte transitive Verben 8^P

0 Stimmen

Dies könnte sich in den letzten Jahren geändert haben. Die Oracle-Dokumentation ermöglicht Schnittstellen als Typen: [link] docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.h‌​tml

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X