web-dev-qa-db-fra.com

Nom de l'interface dans Java

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

Pour illustrer 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. Classe = UserImpl, Interface = User

Où dans la plupart des langues:

Classe = Utilisateur, Interface = IUser

Vous pouvez maintenant dire que vous pouvez toujours choisir le nom le plus descriptif pour l'implémentation de l'utilisateur. Le problème disparaît, mais Java préconise une approche POJO et la plupart des conteneurs IOC utilisent abondamment DynamicProxies. Ces deux choses combinées signifient que vous aurez de nombreuses interfaces avec une seule implémentation de POJO.

Donc, je suppose que ma question se résume à: "Est-il utile de suivre la convention de dénomination d'interface plus large, en particulier à la lumière de l'endroit où Java semble se diriger vers les cadres?"

309
Allain Lalonde

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

  • Le préfixe blesse la lisibilité.

  • L’utilisation d’interfaces dans les clients est la meilleure méthode standard de programmation; les noms des interfaces doivent donc être aussi courts et agréables que possible. Les classes d'implémentation devraient être plus laides pour décourager leur utilisation.

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

312
starblue

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

class User implements IUser

et

class UserImpl implements User

si on ne parle que de conventions de nommage?

Personnellement, je préfère ne PAS précéder l'interface avec I, car je veux coder l'interface et je considère que that est plus important en termes de convention de dénomination. Si vous appelez l'interface IUser, chaque utilisateur de cette classe doit connaître son IUser. Si vous appelez la classe UserImpl, seules la classe et votre conteneur DI connaissent la partie Impl et les consommateurs savent simplement qu'ils travaillent avec un User.

Là encore, les fois où j'ai été obligé d'utiliser Impl parce qu'un meilleur nom ne se présentait pas ont été rares, car l'implémentation est nommée selon à l'implémentation parce que là où c'est important, par exemple.

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
108
tddmonkey

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. Donc, même List est une interface et String est une classe, une méthode peut être transmise à l'une et à l'autre. Cela n'a aucun sens de distinguer visuellement les interfaces.

  2. En général, nous préférerons utiliser des interfaces dans le code client (préférez List à ArrayList, par exemple). Il n’a donc aucun sens de faire des interfaces des exceptions.

  3. La convention de dénomination Java préfère les noms plus longs avec une signification réelle aux préfixes de style hongrois. Donc, ce code sera aussi lisible que possible: une liste représente une liste et un utilisateur représente un utilisateur - pas un utilisateur.

75
Avi

Il existe également une autre convention, utilisée par de nombreux projets open source, y compris 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? Et si la classe n'a pas le préfixe "I", est-ce que je sais alors que ce n'est pas une interface ... la réponse est non, car les conventions ne sont pas toujours suivies, et leur contrôle créera davantage de travail que la convention elle-même enregistre.

70
ng.

Comme l'a dit une autre affiche, il est généralement préférable que les interfaces définissent des capacités et non des types. J'aurais tendance à ne pas "mettre en oeuvre" 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 considère 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'utiliserais toujours des interfaces pour modéliser le comportement, les actions, les capacités, les propriétés, etc., mais pas les types.

En outre, si vous vouliez réellement créer un utilisateur et l'appeler utilisateur, quel est l'intérêt de disposer également d'une interface IUser? Et si vous avez plusieurs types d'utilisateurs devant implémenter une interface commune, qu'est-ce que l'ajout d'un "I" à l'interface vous permet de choisir le nom 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 une classe parent "Utilisateur" avec des sous-classes SuperUser, DefaultUser, AdminUser, AdministrativeContact, etc., dont certaines implémenteront ou non l'implémentation de l'interface Login (Loginable?) Si nécessaire.

45
nairbv

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

quel est le point d'une interface si vous avez une seule implémentation.

vous commencez donc avec une implémentation, c’est-à-dire sans interface. plus tard, vous décidez, eh bien, une interface est nécessaire ici, de sorte que vous convertissez votre classe en une interface.

cela devient alors évident: votre classe d'origine s'appelait User. votre interface s'appelle maintenant utilisateur. vous avez peut-être un UserProdImpl et un UserTestImpl. si vous avez bien conçu votre application, toutes les classes (à l'exception de celles qui instancient User) resteront inchangées et ne remarqueront pas que, soudain, une interface leur est transmise.

il devient donc clair -> Implémentation d'interface utilisateur UserImpl.

36
Andreas Petersson

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 dans 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 qu'il suffit de choisir la convention de dénomination que vous souhaitez, tant que vous êtes cohérent et d'utiliser quelque chose pour montrer aux gens que ce sont des interfaces. Je n'ai pas fait Java depuis quelques années, mais toutes les interfaces seraient simplement dans leur propre répertoire, et c'était la convention. Jamais vraiment eu de problèmes avec elle.

24
Matt Briggs

D'après mon expérience, la convention "I" s'applique aux interfaces 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 à voir que IUser si le seul utilisateur que vous souhaitez utiliser est User. Si vous prévoyez d’utiliser différents types d’utilisateurs - NoviceUser, ExpertUser, etc. - Je m'attendrais à voir une interface User (et peut-être une classe AbstractUser qui implémente des fonctionnalités communes, comme get/setName()).

Je m'attendrais également à ce que les interfaces qui définissent les fonctionnalités - Comparable, Iterable, etc. - soient nommées ainsi, et non comme IComparable ou IIterable.

6
David Koelle

En suivant les bons principes OO, votre code devrait (dans la mesure du possible/possible) 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'interface tels que "User" et "BankAccount" (par exemple), plutôt que "IUser", "UserInterface" ou d'autres variantes.

Les seuls éléments de code qui devraient être concernés par les classes de béton réelles sont les endroits où les classes de béton sont construits. Tout le reste devrait être écrit en utilisant les interfaces.

Si vous le faites, les noms de classe concrets "laids" tels que "UserImpl" devraient être cachés en toute sécurité du reste du code, ce qui permet volontiers de continuer à utiliser les noms d'interface "Nice".

5
KarstenF

= v = Le préfixe "I" est également utilisé dans le framework Wicket, où je me suis habitué rapidement. En général, toute convention qui raccourcit les lourds noms de classe Java est la bienvenue. Cependant, il est embêtant que tout soit alphabétisé sous "I" dans les répertoires et dans le Javadoc.

La pratique de codage de guichet est similaire à Swing, en ce sens que de nombreuses instances de contrôle/widget sont construites en tant que classes internes anonymes avec des déclarations de méthode inline. Ennuyeux, il diffère de 180 ° de Swing en ce que Swing utilise un préfixe ("J") pour les classes implémentées.

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

2
Jym Dyer

Est-ce une convention de nommage plus large dans un sens réel? Je suis plus du côté C++ et pas vraiment sur Java et ses descendants. Combien de communautés linguistiques utilisent la convention I?

Si vous avez une convention de dénomination standard de magasin indépendante de la langue, utilisez-la. Sinon, respectez la convention de dénomination linguistique.

0
David Thornley