Les noms ont la possibilité de donner un sens. Pourquoi voudriez-vous jeter cette opportunité avec Impl?
Tout d’abord, si vous n’avez qu’une seule implémentation, supprimez l’interface. Cela crée ce problème de nommage et n’ajoute rien. Pire encore, des signatures de méthode incohérentes dans les API pourraient poser problème si vous et tous les autres développeurs ne faites pas attention à toujours utiliser uniquement l'interface.
Compte tenu de cela, nous pouvons supposer que chaque interface a ou peut avoir deux implémentations ou plus.
Si vous n'en avez qu'un pour le moment et que vous ne savez pas en quoi l'autre peut être différent, Default est un bon début.
Si vous en avez deux à présent, nommez-les chacun en fonction de son objectif.
Exemple: Nous avons récemment eu une classe concrète Context (en référence à une base de données). On s'est rendu compte qu'il fallait pouvoir représenter un contexte hors ligne. Le nom Context a donc été utilisé pour une nouvelle interface (afin de préserver la compatibilité des anciennes API) et une nouvelle implémentation a été créée, OfflineContext . Mais devinez quoi l'original a été renommé? C'est vrai, ContextImpl ( beurk ).
Dans ce cas, DefaultContext serait probablement correct et les gens l’obtiendraient, mais ce n’est pas aussi descriptif qu’il pourrait l’être. Après tout, si ce n'est pas hors ligne , qu'est-ce que c'est? Nous sommes donc allés avec: OnlineContext .
Cas particulier: utilisation du préfixe "I" sur les interfaces
Une des autres réponses suggéra d'utiliser le préfixe I sur les interfaces. De préférence, vous n'avez pas besoin de faire cela.
Toutefois, si vous avez besoin d'une interface pour les implémentations personnalisées, mais que vous avez également une implémentation concrète principale qui sera utilisée souvent, et que le nom de base qui lui est attribué est trop simple pour être abandonné à une seule interface, vous pouvez envisager d'ajouter "Je" à l'interface (cependant, c'est tout à fait bien si ça ne vous convient pas, à vous et à votre équipe).
Exemple: De nombreux objets peuvent être un "EventDispatcher". Pour les API, cela doit être conforme à une interface. Mais vous souhaitez également fournir un répartiteur d'événements de base pour la délégation. DefaultEventDispatcher conviendrait, mais il est un peu long et si vous voyez souvent son nom, vous préférerez peut- être utiliser le nom de base EventDispatcher pour la classe concrète et implémenter IEventDispatcher pour les implémentations personnalisées:
/* Option 1, traditional verbose naming: */
interface EventDispatcher { /* interface for all event dispatchers */ }
class DefaultEventDispatcher implements EventDispatcher {
/* default event dispatcher */
}
/* Option 2, "I" abbreviation because "EventDispatcher" will be a common default: */
interface IEventDispatcher { /* interface for all event dispatchers */ }
class EventDispatcher implements IEventDispatcher {
/* default event dispatcher. */
}
if you will only ever have one implementation, do away with the interface
- sauf si vous souhaitez tester le composant, auquel cas vous pouvez conserver cette interface afin de créer MockOrder, OrderStub ou similaire.Je décide de la dénomination par le cas d'utilisation de l'interface.
Si l'interface est utilisée pour le découplage , je choisis
Impl
pour les implémentations.Si le but de l'interface est l'abstraction comportementale , les implémentations sont nommées en fonction de ce qu'elles font concrètement. J'y ajoute souvent le nom de l'interface. Donc, si l'interface est appelée
Validator
, je l'utiliseFooValidator
.Je trouve que
Default
c'est un très mauvais choix. D'abord, il pollue les fonctionnalités de complétion de code, car les noms commencent toujours par. L'autre chose est qu'un défaut est sujet à changement avec le temps. Ainsi, ce qui pourrait être un défaut par défaut peut être une fonctionnalité obsolète. Donc, soit vous commencez toujours à renommer vos classes dès que les valeurs par défaut changent ou vous vivez avec des noms trompeurs.la source
Je suis d' accord avec la réponse de Nicole ( en particulier que l'interface est probablement pas nécessaire dans la plupart des cas), mais pour le bien de la discussion , je vais jeter à une autre alternative supplémentaire que
OrderImpl
etDefaultOrder
: cacher la mise en œuvre derrière une méthode de fabrication statique commeOrders.create()
. Par exemple:Avec cette approche, l'implémentation peut être une classe interne anonyme, ou une classe privée avec
Default
ouImpl
dans le nom, ou encore nommée autrement. Quel que soit le choix qui est fait, l’appelant n’a pas besoin de s’inquiéter, vous bénéficiez donc d’une plus grande flexibilité maintenant et plus tard, lorsque vous décidez de le modifier.Les classes d’utilitaires
java.util.Collections
etjava.util.concurrent.Executors
dont les méthodes renvoient des implémentations masquées sont d’excellents exemples de ce modèle en pratique . Comme le mentionne Effective Java (élément 1), ce modèle peut aider à réduire le "poids conceptuel" de l’API.la source
Je vais toujours pour
OrderImpl
simplement parce que cela apparaît par ordre alphabétique juste après l'Order
interface.la source
Vous pouvez nommer l'interface avec le préfixe I (IW Whatever) et ensuite faire la mise en œuvre.
Les conventions officielles du code Java ne parlent pas de ce type de nommage pour les interfaces, mais ce type de nommage facilite la reconnaissance et la navigation.
la source
Je pense que bien que Default puisse avoir un sens dans certains cas, il serait plus utile de décrire la mise en œuvre. Donc , si votre interface est
UserProfileDAO
alors vos implémentations peuvent êtreUserProfileSQLDAO
ouUserProfileLDAPDAO
quelque chose comme ça.la source
si possible, nommez-le après quoi / comment il fait sa chose.
En général, la pire approche consiste à le nommer en fonction de son utilisation.
Si elle est supposée être utilisée comme classe de base pour la mise en oeuvre, vous pouvez utiliser BaseX ou AbstractX (si elle est abstraite (mais essayez de presser ce qu'elle fait, car si vous ne faites rien, vous ne la créeriez pas, vous avez déjà Si elle fournit les fonctionnalités les plus simples possibles et qu’elle est censée être utilisée directement (sans l’étendre) lorsque cette fonctionnalité suffit, vous pouvez l’appeler SimpleX ou BasicX.
S'il est utilisé sauf si une autre implémentation est fournie, nommez-le DefaultX
la source
La plupart de ces réponses décrivent ce qui est fait mais pas pourquoi.
Qu'est-il arrivé aux principes OO? Qu'est-ce que Impl me dit à propos d'un cours et comment l'utiliser? Vous devriez être préoccupé par la compréhension des usages et non de la façon dont il est construit.
Si je crée une interface Person, qu'est-ce qu'un PersonImpl? Sans signification. Au moins, DefaultPerson me dit que celui qui l'a codé n'aurait pas dû créer une interface.
Les interfaces typent pour le polymorphisme et doivent être utilisées telles quelles.
la source