Nom de l'interface en Java [fermé]


324

La plupart des langues OO préfixent leurs noms d'interface par un I majuscule, pourquoi Java ne fait-il pas cela? Quelle était la raison pour ne pas suivre cette convention?

Pour démontrer ce que je veux dire, si je voulais avoir une interface utilisateur et une implémentation utilisateur, j'aurais deux choix en Java:

  1. Classe = utilisateur, interface = interface utilisateur
  2. Class = UserImpl, Interface = User

Où dans la plupart des langues:

Classe = utilisateur, interface = utilisateur

Maintenant, vous pourriez faire valoir que vous pouvez toujours choisir un nom le plus descriptif pour l'implémentation utilisateur et le problème disparaît, mais Java pousse une approche POJO des choses et la plupart des conteneurs IOC utilisent largement DynamicProxies. Ces deux choses ensemble signifient que vous aurez beaucoup d'interfaces avec une seule implémentation POJO.

Donc, je suppose que ma question se résume à: "Vaut-il la peine de suivre la convention de dénomination d'interface plus large, surtout à la lumière de l'orientation vers laquelle les cadres Java semblent se diriger?"


61
"Où dans la plupart des langues"? Quelles langues en plus des .Net?
wds

2
Différentes communautés linguistiques ont des conventions d'appellation différentes, et cela est vrai depuis très, très longtemps. Découvrir l'origine des conventions de dénomination est parfois essentiellement une recherche folklorique.
David Thornley

4
Eclipse est une valeur aberrante importante qui utilise Java avec une dénomination de style IFoo. wiki.eclipse.org/Naming_Conventions
David Leonard

2
Si vous jetez un oeil à noms des interfaces dans Android SDK (Java ainsi), vous verrez que ils ont utilisé la convention d'avoir mot interface à l'extrémité d'un nom d'interface, comme NetworkInterface, DialogInterface, etc.
sandalone

21
Comment cette question peut-elle être «fermée comme non constructive» alors qu'elle est si populaire et intéresse tant de gens?
2014

Réponses:


329

Je préfère ne pas utiliser de préfixe sur les interfaces:

  • Le préfixe nuit à la lisibilité.

  • L'utilisation d'interfaces dans les clients est la meilleure façon standard de programmer, donc les noms d'interfaces doivent être aussi courts et agréables que possible. L'implémentation des classes devrait être plus laide pour décourager leur utilisation.

  • Lors du passage d'une classe abstraite à une interface, une convention de codage avec préfixe I implique de renommer toutes les occurrences de la classe --- pas bon!


12
Entièrement d'accord. Encore une clé à taper si vous utilisez la saisie semi-automatique. Beaucoup de fichiers commençant par un I.
Kalecser

85
Tout IDE décent facilite le changement de code dans la façon dont vous décrivez. De plus, lorsque je passe d'une classe abstraite à une interface, je suis sûr que vos clients devront de toute façon recompiler.
Allain Lalonde

63
Super fin, mais: Il n'a pas d' importance du tout si un IDE permet de changer le nom de quelque chose de facile. Le code utilisant une instance d'un type ne devrait jamais, jamais se soucier si ce type est une interface ou une classe ou quoi. En tant que tel, exposer un tel détail dans le nom du type est inutile et nuisible à la compréhension. Le type et le contrat qu'il expose sont ce qui compte!
ColinD

11
De plus, si vous suivez la voie de IFoo, ne devrait-il pas s'agir de CFoo pour l'implémentation et bien sûr en cas d'échec une méthode lancerait un EFoo.
Robin

57
"Le préfixe nuit à la lisibilité" est purement subjectif. Comme la plupart des conventions de dénomination. Il importe plus que votre équipe se mette d'accord sur ce qu'il faut faire pour que la base de code soit cohérente.
dreadwail

121

Y a-t-il vraiment une différence entre:

class User implements IUser

et

class UserImpl implements User

si tout ce dont nous parlons est de nommer les conventions?

Personnellement, je préfère ne PAS précéder l'interface Icar je veux coder sur l'interface et je considère que c'est plus important en termes de convention de dénomination. Si vous appelez l'interface, IUserchaque consommateur de cette classe doit connaître son an IUser. Si vous appelez la classe, UserImplseules la classe et votre conteneur DI connaissent la Implpièce et les consommateurs savent simplement qu'ils travaillent avec a User.

Là encore, les fois où j'ai été forcé d'utiliser Implparce qu'un meilleur nom ne se présente pas ont été rares, car l'implémentation est nommée en fonction de l'implémentation parce que c'est là que c'est important, par exemple

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO

Je pense que vous voudriez savoir que c'est un DAO car cela décrit les fonctionnalités générales sans avoir besoin d'ouvrir la classe. Si je regarde les fichiers de classe d'un projet, il est facile de voir tous les DAO en recherchant * DAO
Patrick

6
DAO est un modèle bien connu pour l'accès à la base de données, donc avoir le modèle dans le nom permet de savoir facilement ce que fait la classe simplement en regardant son nom. PS Il serait préférable de suivre strictement la notation chameau ("AccountDao") comme dans mina.apache.org/changes-between-2x-and-1x.html
Esko Luontola

4
@marker, ce n'est pas comme avoir un I pour indiquer une interface. DAO vous indique que la classe ou l'interface est un objet pour accéder aux données de compte, ce que fait l'objet. Avoir un I vous dit que c'est une interface, qui n'a rien à voir avec l'objet lui-même mais la sémantique du langage
tddmonkey

Comme vous le présentez, son préfixe vs suffixe.
Andrei Rînea

3
@Andrei: Non, c'est la sémantique ("DAO") contre la décoration inutile d'un artefact de langage ("I" comme dans l'interface; un fait, qui est quand même mentionné dans le code "interface IFoo ...")
Dirk

75

Il peut y avoir plusieurs raisons pour lesquelles Java n'utilise généralement pas la convention IUser.

  1. Une partie de l'approche orientée objet consiste à ne pas avoir à savoir si le client utilise une interface ou une classe d'implémentation. Ainsi, même List est une interface et String est une classe réelle, une méthode peut être transmise aux deux - il n'est pas logique de distinguer visuellement les interfaces.

  2. En général, nous préférerons en fait l'utilisation d'interfaces dans le code client (préférons List à ArrayList, par exemple). Il n'est donc pas logique de faire ressortir les interfaces en tant qu'exceptions.

  3. La convention de nommage Java préfère les noms plus longs avec des significations réelles aux préfixes de style hongrois. Ainsi, ce code sera aussi lisible que possible: une liste représente une liste, et un utilisateur représente un utilisateur - pas un utilisateur.


72

Il existe également une autre convention, utilisée par de nombreux projets open source, dont Spring.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

Personnellement, je n'aime pas le préfixe "I" pour la simple raison que c'est une convention facultative. Donc, si j'adopte cela, IIOPConnection signifie-t-il une interface pour IOPConnection? Que se passe-t-il si la classe n'a pas le préfixe "I", puis-je savoir que ce n'est pas une interface .. la réponse ici est non, car les conventions ne sont pas toujours suivies, et les contrôler créera plus de travail que la convention elle-même enregistre.


J'aime cela, car cela vous aide également à utiliser les interfaces pour les dépendances externes plutôt que de coupler les classes.
Matt Briggs

47

Comme l'a dit une autre affiche, il est généralement préférable que les interfaces définissent les capacités et non les types. J'aurais tendance à ne pas «implémenter» quelque chose comme un «utilisateur», et c'est pourquoi «IUser» n'est souvent pas vraiment nécessaire de la manière décrite ici. Je vois souvent les classes comme des noms et les interfaces comme des adjectifs:

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

Parfois, un adjectif n'a pas de sens, mais j'utilise généralement des interfaces pour modéliser le comportement, les actions, les capacités, les propriétés, etc., pas les types.

De plus, si vous ne deviez vraiment créer qu'un seul utilisateur et l'appeler utilisateur, à quoi bon avoir également une interface utilisateur? Et si vous allez avoir quelques types d'utilisateurs différents qui ont besoin d'implémenter une interface commune, qu'est-ce que l'ajout d'un "I" à l'interface vous évite de choisir les noms des implémentations?

Je pense qu'un exemple plus réaliste serait que certains types d'utilisateurs doivent pouvoir se connecter à une API particulière. Nous pourrions définir une interface de connexion, puis avoir une classe parent "Utilisateur" avec des sous-classes SuperUser, DefaultUser, AdminUser, AdministrativeContact, etc., dont certaines implémenteront ou non l'interface de connexion (connectable?) Si nécessaire.


Je pense que les exemples que vous fournissez pour prendre en charge les "interfaces en tant qu'adjectifs" sont biaisés, car ces interfaces sont destinées à ressembler davantage à des mix-ins (ou traits). Ainsi, les interfaces sont bonnes pour les adjectifs et les noms - mais probablement pas pour indefinite transitive verbs 8 ^ P
Stevel

Cela pourrait changer au cours des dernières années. Le docu oracle. autorise les interfaces en tant que types: [link] docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html
karlihnos

38

Bob Lee a dit une fois dans une présentation:

quel est l'intérêt d'une interface si vous n'avez qu'une seule implémentation.

vous commencez donc avec une seule implémentation, c'est-à-dire sans interface. plus tard, vous décidez, eh bien, il y a un besoin d'une interface ici, donc vous convertissez votre classe en interface.

alors cela devient évident: votre classe d'origine s'appelait Utilisateur. votre interface s'appelle désormais Utilisateur. vous avez peut-être un UserProdImpl et un UserTestImpl. si vous avez bien conçu votre application, chaque classe (à l'exception de celles qui instancient l'utilisateur) sera inchangée et ne remarquera pas que tout à coup, elles passent une interface.

il devient donc clair -> Interface utilisateur de mise en œuvre UserImpl.


18
L'utilisation d'interfaces permet de tester le développement piloté. Nous avons rencontré de nombreux problèmes avec notre modèle de domaine et nos tests, car nous avons décidé de NE PAS utiliser d'interfaces. Un de mes amis a cité un jour: "Tout est une interface, cela vous sauvera à long terme."
hooknc

4
Support proxy moqueur et facile. Je suis sûr qu'il existe également d'autres raisons de fournir des interfaces.
MetroidFan2002

3
Comme je l'ai dit récemment à un collègue, l'introduction d'une interface ne coûte rien mais peut vous faire gagner beaucoup de temps plus tard.
tddmonkey

2
Si vous pourriez avoir d'autres implémentations dans un avenir proche ou moyen, une interface serait un plus.
Stef

3
Je n'aime pas l'argument "J'ai peut-être besoin d'un autre implément dans le futur". Je préfère une approche YAGNI: ne prévoyez pas des choses qui ne se sont pas encore produites.
David Lavender

24

En C # c'est

public class AdminForumUser : UserBase, IUser

Java dirait

public class AdminForumUser extends User implements ForumUserInterface

Pour cette raison, je ne pense pas que les conventions soient presque aussi importantes en java pour les interfaces, car il existe une différence explicite entre l'héritage et la mise en œuvre de l'interface. Je dirais simplement choisir n'importe quelle convention de dénomination que vous souhaitez, tant que vous êtes cohérent et utilisez quelque chose pour montrer aux gens que ce sont des interfaces. Je n'ai pas fait de java depuis quelques années, mais toutes les interfaces seraient simplement dans leur propre répertoire, et c'était la convention. Je n'ai jamais vraiment eu de problèmes avec ça.


22
Je suis peut-être un mauvais codeur Java, mais je préfère le style C #, cela signifie que toutes les interfaces commencent par le préfixe «I» :)
davs

7
Je ne sais pas d'où vous et les autres tirez cette supposée convention. Ce n'est pas évident dans les bibliothèques Java ...
ChiefTwoPencils

6

D'après mon expérience, la convention "I" s'applique aux interfaces qui sont destinées à fournir un contrat à une classe, en particulier lorsque l'interface elle-même n'est pas une notion abstraite de la classe.

Par exemple, dans votre cas, je ne m'attendrais qu'à voir IUsersi le seul utilisateur que vous avez l'intention d'avoir est User. Si vous prévoyez d'avoir différents types d'utilisateurs - NoviceUser, ExpertUseretc. - je me attends de voir une Userinterface (et, peut - être, une AbstractUserclasse qui implémente une fonctionnalité commune, commeget/setName() ).

Je me attends également des interfaces qui définissent les capacités - Comparable, Iterableetc. - d'être nommé comme ça, et pas comme IComparableou IIterable.


Si le seul utilisateur que vous avez l'intention d'avoir est User, pourquoi ne pas simplement utiliser User au lieu de l'interface?
Carighan

3
Dans certaines architectures client / serveur, le côté client doit connaître les interfaces sans avoir besoin des implémentations serveur lourdes.
David Koelle

5

En suivant de bons principes OO, votre code devrait (autant que possible / pratique) dépendre d'abstractions plutôt que de classes concrètes. Par exemple, il est généralement préférable d'écrire une méthode comme celle-ci:

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

que cela:

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

Si vous suivez cette idée, je maintiens que votre code sera plus lisible si vous donnez des noms d'interfaces comme "User" et "BankAccount" (par exemple), plutôt que "IUser", "UserInterface" ou d'autres variantes.

Les seuls morceaux de code qui devraient se soucier des classes concrètes réelles sont les endroits où les classes concrètes sont construites. Tout le reste doit être écrit à l'aide des interfaces.

Si vous faites cela, alors les noms de classes concrets "moches" comme "UserImpl" devraient être cachés en toute sécurité du reste du code, ce qui peut continuer joyeusement en utilisant les "jolis" noms d'interface.


Mais pourquoi s'embêter à créer une interface correspondante pour chaque classe de votre programme alors que vous n'avez besoin d'interfaces que pour une ou deux choses?
LegendLength

3

= v = Le préfixe "I" est également utilisé dans le framework Wicket, où je me suis habitué rapidement. En général, je salue toute convention qui raccourcit les noms de classe Java encombrants. C'est un problème, cependant, que tout soit alphabétisé sous "I" dans les répertoires et dans le Javadoc.

La pratique de codage Wicket est similaire à Swing, dans la mesure où de nombreuses instances de contrôle / widget sont construites comme des classes internes anonymes avec des déclarations de méthode en ligne. De façon ennuyeuse, il diffère à 180 ° de Swing en ce que Swing utilise un préfixe ("J") pour les classes d'implémentation.

Le suffixe "Impl" est une abréviation virile et ne s'internationalise pas bien. Si seulement nous avions au moins opté pour "Imp", ce serait plus mignon (et plus court). "Impl" est utilisé pour IOC, en particulier Spring, donc nous sommes en quelque sorte coincés avec pour l'instant. Cela devient un peu schizo en suivant 3 conventions différentes dans trois parties différentes d'une même base de code.


0

S'agit-il d'une convention de dénomination plus large dans un sens réel? Je suis plus sur le côté C ++, et pas vraiment sur Java et ses descendants. Combien de communautés linguistiques utilisent la convention I?

Si vous avez ici une convention de dénomination standard de boutique indépendante de la langue, utilisez-la. Sinon, suivez la convention de dénomination de la langue.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.