web-dev-qa-db-fra.com

Quelle convention de dénomination utilisez-vous pour la couche de service dans une application Spring MVC?

Je n'arrive pas à trouver une bonne convention de dénomination pour la couche de service dans une application Spring. Pour chaque classe de la couche service, j'écris d'abord l'interface qu'elle doit implémenter, puis la classe réelle. Ainsi, par exemple, j'ai l'interface suivante:

public interface UserAccountManager{
   public void registerUser(UserAccount newUserAccount);
   public void resetPassword(UserAccount userAccount);
...
}

Et puis la classe d'implémentation ...

Ce qui me dérange ici est UserAccountManager est un bon nom pour la classe d'implémentation, donc je suis obligé de lui donner un nom stupide comme SimpleUserAccountManager ou UserAccountDbManager. Quelles sont les conventions que vous avez utilisées jusqu'à présent? Est-ce une bonne idée de mettre les classes d'implémentation dans un package différent et de leur donner les mêmes noms que les interfaces? Que pensez-vous également de l'utilisation des noms se terminant par Manager par rapport aux noms se terminant par Service?

42
Vasil

Spring lui-même donne aux interfaces des noms génériques, puis nomme les classes en fonction des détails de l'implémentation. Voici un exemple qui vient à l'esprit:

interface: Controller
abstract classes: AbstractController, AbstractCommandController, 
                  SimpleFormController, MultiActionController

Je ne pense pas que des noms comme SimpleUserAccountManager ou UserAccountDbManager soient stupides, car ils véhiculent des informations concernant la mise en œuvre du gestionnaire/service.

Ce que je trouve stupide, c'est la convention courante pour ajouter le suffixe "Impl" aux classes d'implémentation:

my/package/UserAccountManager
my/package/impl/UserAccountManagerImpl

Certaines personnes préfèrent cependant cela.

18
kgiannakakis

Voici ce que nous utilisons:

  • XxxDAO (Data Access Object) - Responsable de l'interaction directe avec EntityManager, JDBC DataSource, système de fichiers, etc. Ne doit contenir que la logique de persistance, telle que SQL ou JPA-QL, mais pas (ou aussi peu) que possible) la logique métier. Doit être accessible uniquement à partir des gestionnaires.
  • XxxManager - Gère les entités au niveau de l'entreprise, effectue généralement des opérations CRUD, mais ajoute la logique métier requise.
  • XxxService - La couche où réside la logique métier. Doit "parler" dans des objets simples - cordes, pouces, etc. - autant que possible.
  • XxxController - La couche d'interaction UI. Devrait s'adresser uniquement aux Services.
  • XxxUtilities/XxxUtils - Les méthodes sans état auxiliaires ne doivent dépendre d'aucun service du système. Si vous avez besoin d'une telle dépendance, convertissez la classe d'utilité en service ou ajoutez le résultat du service en tant que paramètre.

Pour l'implémentation, nous ajoutons le suffixe Impl (XxxServiceImpl), pour le distinguer de l'interface, et s'il y a plusieurs implémentations ou si nous voulons ajouter des informations supplémentaires, nous l'ajoutons comme préfixe (JdbcXxxDaoImpl, GoogleMapsGeocodingServiceImpl, etc.). Les noms de classes deviennent un peu longs de cette façon, mais ils sont très descriptifs et auto-documentés.

57
David Rabinowitz

Pour l'exemple que vous donnez, j'utiliserais des noms d'implémentation qui reflètent comment la classe effectue les opérations, comme HibernateUserAccountManager, ou JPAUserAccountManager, ou JDBCUserAccountManager, etc., ou peut-être simplement UserAccountManagerDAO.

7
skaffman

Il n'est évidemment pas important en soi que les noms de classe se terminent par Manager ou Service. Ce qui est important, d'une manière générale, c'est que les noms véhiculent avec précision ce qui est modélisé. Et c'est le noeud du problème: les "services" ou les "gestionnaires" ne sont pas des objets du monde réel que nous essayons de modéliser dans nos objets logiciels. Au contraire, ce sont des endroits où nous collectons un tas de méthodes qui font des choses qui ne correspondent tout simplement pas aux responsabilités des objets que nous faisons devons/voulons modéliser.

Personnellement, je préfère le "service", mais uniquement parce que "manager" semble être quelque chose que l'on pourrait réellement modéliser, c'est-à-dire qu'il pourrait y avoir des gestionnaires du monde réel que nos objets "-manager" représentent. Mais le point est entièrement académique et je reconnais immédiatement que cela ne fait aucune différence pratique.

Ce qui compte vraiment est généralement beaucoup plus fondamental que de tels points: avoir un modèle bien compris par tous les acteurs du développement. Si mon expérience est quelque chose qui passe, c'est rarement le cas. Mon conseil à ceux qui demandent si "manager" ou "service" est la bonne métaphore est donc: Lancez une pièce, assurez-vous que tout le monde est au courant de la convention, et passez votre temps à réfléchir et à discuter de sujets qui comptent!

4
The Dag

Je pense que le suffixe de nommage Service vs Manager est purement une préférence. Le seul moment où le "service" nous a causé de la confusion est lorsque nous avons également des services Web au-dessus de notre couche de services. Sur certains projets, nous avons simplement appelé les classes de services Web des courtiers car elles ne faisaient que traduire ou négocier l'appel de service Web en un appel à notre niveau de service.

Je suis d'accord avec kgiannakakis que suffixer vos implémentations avec "Impl" n'est pas une bonne approche. J'ai également rencontré des meilleures pratiques de codage qui mentionnent de ne pas le faire. Nommer l'interface après l'abstraction est la meilleure pratique généralement acceptée. Nommer la classe d'implémentation après l'interface avec un indicateur de son objectif ou de son type, comme l'a suggéré kgiannakakis, semble être l'approche généralement acceptée.

Lorsque nous avons des DAO basés sur des services Web et des DAO basés sur ORM, nous utilisons à la fois des packages et des noms de classe pour différencier les classes d'implémentation de leurs interfaces et les unes des autres. Je pense que mettre les implémentations dans différents packages se résume au nombre de classes que vous avez dans le package, à la façon dont elles sont implémentées différemment et à combien vous souhaitez diviser les choses.

3
DavidValeri

Pour moi, une classe de service consiste à implémenter un cas d'utilisation, je le nomme donc en fonction du type d'utilisateur pour lequel le service agit. Donc, si j'ai une application avec des rôles différents, par exemple clients, personnes chargées de la commande complète, personnes chargées de la saisie des données et administrateurs, j'aurais probablement un service client, un service commandeFulfillment, un service DataEntryService et un service AdminService. Je pense que nommer un service en fonction du type de données récupérées ou manipulées est un anti-modèle. Donc, en devinant que la manipulation UserAccount serait le domaine d'un administrateur, je l'appellerais probablement "AdminService".

2
Nathan Hughes

Vous pouvez également nommer l'interface IUserAccountManager (cette convention est utilisée dans Eclipse RCP, par exemple), puis utiliser UserAccountManager pour l'implémentation par défaut.

2
Ilya Boyandin

Lié à la différence entre les gestionnaires et les services: je dirais utiliser une couche pour la logique métier (couche service OR couche gestionnaire) aussi longtemps que possible.

Dès que cette couche se complique (supposons que vous ayez utilisé des services), vous pouvez ajouter des responsables chargés de déléguer à un service ou à un autre, mais gardez la logique métier à l'intérieur des services.

Je garderais donc les services simples, utiliserais des gestionnaires pour gérer les services et garderais la logique métier à l'intérieur des services.

Je suis également d'accord pour éviter le suffixe Impl pour les implémentations et éviter le suffixe I pour les interfaces. À titre d'exemple, nommer l'interface "Controller" et nommer l'implémentation "SimpleController" ou "UserController" me semble mieux.

1
Anghel Contiu

En supposant que ceux-ci concernent les services REST, je pense que votre convention de dénomination URI est plus importante que le nom des services d'implémentation sous-jacents, car ces derniers seront largement invisibles pour les clients. Bien sûr, vous voulez un nommage cohérent en interne, mais ce n'est pas aussi crucial.

Certaines REST que nous avons utilisées: http://soaprobe.blogspot.co.uk/2012/10/soa-rest-service-naming-guideline.html (mon blog)

1
Robert Morschel