Comment nommez-vous les différentes classes/interfaces que vous créez? Parfois, je n'ai pas d'informations d'implémentation à ajouter au nom de l'implémentation - comme l'interface FileHandler
et la classe SqlFileHandler
.
Lorsque cela se produit, je nomme généralement l'interface dans le nom "normal", comme Truck
, et nomme la classe actuelle TruckClass
.
Comment nommez-vous les interfaces et les classes à cet égard?
Nommez votre Interface
ce que c'est. Truck
. Non ITruck
parce que ce n'est pas un ITruck
c'est un Truck
.
Un Interface
dans Java est un Type . Ensuite, vous avez DumpTruck
, TransferTruck
, WreckerTruck
, CementTruck
, etc. que implement Truck
.
Lorsque vous utilisez Interface
à la place d'une sous-classe, il vous suffit de le convertir en Truck
. Comme dans List<Truck>
. Mettre I
devant est juste style hongrois notation tautologie qui n’ajoute rien mais plus de choses à taper dans votre code.
Tous les modernes Java de la marque IDE Interfaces et implémentations et ce qui n'est pas sans cette notation idiote. N'appelez pas cela TruckClass
c'est-à-dire tautologie aussi grave que la IInterface
tautologie.
Si c'est une implémentation, c'est une classe. La seule véritable exception à cette règle, et il y a toujours des exceptions, pourrait être quelque chose comme AbstractTruck
. Étant donné que seules les sous-classes verront cela et que vous ne devriez jamais transtyper vers une classe Abstract
, il ajoute des informations indiquant que la classe est abstraite et comment elle doit être utilisée. Vous pouvez toujours trouver un meilleur nom que AbstractTruck
et utiliser BaseTruck
ou DefaultTruck
à la place car le abstract
est dans la définition. Mais comme les classes Abstract
ne devraient jamais faire partie d'une interface publique, je pense qu'il s'agit d'une exception acceptable à la règle. Rendre les constructeurs protected
permet de franchir ce fossé.
Et le suffixe Impl
est simplement plus de bruit. Plus de tautologie. Tout ce qui n'est pas une interface est une implémentation, même les classes abstraites qui sont des implémentations partielles. Allez-vous mettre ce stupide suffixe Impl
sur chaque nom de chaque Classe ?
La Interface
est un contrat sur ce que les méthodes et propriétés publiques doivent prendre en charge, il s'agit également de Type informations. Tout ce qui implémente Truck
est un Type de Truck
.
Examinez la bibliothèque standard Java. Voyez-vous IList
, ArrayListImpl
, LinkedListImpl
? Non, vous voyez List
et ArrayList
, et LinkedList
. Voici un Nice article sur cette question exacte. Chacune de ces conventions de nommage stupides de préfixes/suffixes enfreint également le principe SEC .
De même, si vous ajoutez DTO
, JDO
, BEAN
ou d'autres suffixes répétitifs stupides aux objets, ils appartiennent probablement à un package à la place de tous ces suffixes . Les espaces de noms correctement empaquetés sont auto-documentés et réduisent toutes les informations redondantes inutiles dans ces schémas de nommage propriétaires vraiment mal conçus, auxquels la plupart des endroits ne adhèrent même pas de manière cohérente en interne.
Si tout ce que vous pouvez faire pour rendre votre nom Class
unique est simplement suffixé de Impl
, vous devez alors repenser à avoir un Interface
. Ainsi, lorsque vous avez une situation où vous avez une Interface
et une seule Implementation
qui n'est pas uniquement spécialisée dans la Interface
dont vous n'avez probablement pas besoin la Interface
.
J'ai vu des réponses suggérant que, si vous n'avez qu'une seule implémentation, vous n'avez pas besoin d'une interface. Cela va à l’encontre du principe de la Depencency Injection/Inversion of Control (ne nous appelez pas, nous vous appellerons!).
Alors oui, il existe des situations dans lesquelles vous souhaitez simplifier votre code et le rendre facilement testable en vous basant sur des implémentations d'interface injectées (qui peuvent également être mandatées - votre code ne le sait pas!). Même si vous ne disposez que de deux implémentations - une simulation de test et une injection dans le code de production - cela ne rend pas superflue le fait d’avoir une interface. Une interface bien documentée établit un contrat, qui peut également être maintenu par une implémentation fictive stricte à des fins de test.
en fait, vous pouvez établir des tests qui permettent aux implants d'implémenter le contrat d'interface le plus strict (en générant des exceptions pour des arguments qui ne doivent pas être nuls, etc.) et de détecter les erreurs lors des tests, en utilisant une implémentation plus efficace dans le code de production (en ne vérifiant pas les arguments ne pas être null pour null car le modèle a jeté des exceptions dans vos tests et vous savez que les arguments ne sont pas nuls en raison de la correction du code après ces tests, par exemple).
L’injection de dépendance/IOC peut être difficile à comprendre pour un nouveau venu, mais une fois que vous aurez compris son potentiel, vous aurez envie de l’utiliser partout et vous vous retrouverez à faire des interfaces tout le temps - même s’il n’y en aura qu’une ( production réelle) mise en œuvre.
Pour cette implémentation (vous pouvez en déduire, et vous auriez raison, que je pense que les tests de test doivent s'appeler Mock (Nom de l'interface)), je préfère le nom Par défaut (Nom de l'interface). Si une implémentation plus spécifique se présente, elle peut être nommée de manière appropriée. Cela évite également le suffixe impl que je n'aime pas particulièrement (si ce n'est pas une classe abstraite, bien sûr, c'est un "impl"!).
Je préfère également "Base (InterfaceName)" par opposition à "Abstract (InterfaceName)", car il existe certaines situations dans lesquelles vous souhaitez que votre classe de base devienne instanciable plus tard, mais vous vous retrouvez désormais avec le nom "Abstract (InterfaceName)". et cela vous oblige à renommer la classe, ce qui peut entraîner une petite confusion - mais si elle était toujours Base (InterfaceName), la suppression du modificateur abstrait ne change pas la classe.
Le nom de l'interface doit décrire le concept abstrait représenté par l'interface. Toute classe d'implémentation doit avoir une sorte de traits spécifiques pouvant être utilisés pour lui donner un nom plus spécifique.
S'il n'y a qu'une seule classe d'implémentation et que vous ne pouvez penser à rien qui la rende spécifique (implicite en voulant l'appeler -Impl
]), il semble alors qu'il n'y a aucune justification pour avoir une interface du tout.
J'ai tendance à suivre les pseudo-conventions établies par Java Core/Sun, par exemple. dans les classes de collections:
List
- interface pour l'objet "conceptuel"ArrayList
- implémentation concrète de l'interfaceLinkedList
- implémentation concrète de l'interfaceAbstractList
- implémentation abstraite "partielle" pour assister les implémentations personnaliséesAuparavant, je modélisais mes classes d'événements après le paradigme AWT Event/Listener/Adapter.
La convention standard C #, qui fonctionne assez bien dans Java aussi, consiste à préfixer toutes les interfaces avec un I
- de sorte que votre interface de gestionnaire de fichiers sera IFileHandler
et votre interface de camion ITruck
. Il est cohérent et permet de distinguer facilement les interfaces des classes.
J'aime les noms d'interface qui indiquent le contrat décrit par une interface, tels que "Comparable" ou "Serializable". Les noms comme "Camion" ne décrivent pas vraiment le camionnage - quelles sont les capacités d'un camion?
Concernant les conventions: j'ai travaillé sur des projets où chaque interface commence par un "I"; Bien que cela soit quelque peu étranger aux conventions Java, il est très facile de rechercher des interfaces. En dehors de cela, le suffixe "Impl" est un nom par défaut raisonnable.
Certaines personnes n'aiment pas cela, et il s'agit davantage d'une convention .NET que Java, mais vous pouvez nommer vos interfaces avec un préfixe majuscule I, par exemple:
IProductRepository - interface
ProductRepository, SqlProductRepository, etc. - implementations
Les personnes qui s'opposent à cette convention d'appellation peuvent faire valoir que vous ne devez pas vous soucier de travailler avec une interface ou un objet dans votre code, mais je trouve qu'il est plus facile de lire et de comprendre à la volée.
Je ne nommerais pas la classe d'implémentation avec un suffixe "Class". Cela peut prêter à confusion, car vous pouvez réellement utiliser des objets "class" (c'est-à-dire Type) dans votre code, mais dans votre cas, vous ne travaillez pas avec l'objet class, vous travaillez simplement avec un objet ancien. .
TruckClass
ressemble à une classe de Truck
, je pense que la solution recommandée consiste à ajouter le suffixe Impl
. A mon avis, la meilleure solution consiste à contenir dans le nom de l’implémentation des informations sur ce qui se passe dans cette implémentation particulière (comme avec l’interface List
et les implémentations: ArrayList
ou LinkedList
), mais Parfois, vous avez juste une implémentation et devez avoir une interface en raison d'une utilisation à distance (par exemple), alors (comme mentionné au début) Impl
est la solution.
J'utilise les deux conventions:
Si l'interface est une instance spécifique d'un modèle bien connu (par exemple, Service, DAO), il se peut qu'elle n'ait pas besoin d'un "I" (par exemple, UserService, AuditService, UserDao), tout fonctionnera correctement sans le "I", car détermine le modèle méta.
Toutefois, si vous avez un élément unique ou double (généralement pour un modèle de rappel), il est alors utile de le distinguer d'une classe (par exemple, IAsynchCallbackHandler, IUpdateListener, IComputeDrone). Il s’agit d’interfaces spéciales conçues pour un usage interne; parfois, l’interface IInterface attire l’attention sur le fait qu’un opérande est en réalité une interface, de sorte qu’il est immédiatement clair au premier abord.
Dans d'autres cas, vous pouvez utiliser le I pour éviter les collisions avec d'autres classes concrètes connues (ISubject, IPrincipal vs Subject ou Principal).