web-dev-qa-db-fra.com

La couche de service renvoie le DTO au contrôleur mais en a besoin pour renvoyer le modèle pour d'autres services

Suite à ce post https://stackoverflow.com/questions/21554977/should-services-always-return-dtos-or-can-they-also-return-domain-models et les meilleures pratiques en matière de logiciels Suggestions d'arc par Martin Fowler

Une couche de service définit la limite d'une application [Cockburn PloP] et son ensemble d'opérations disponibles du point de vue de l'interface des couches clientes. Il encapsule la logique métier de l'application

J'ai un problème pour ce faire, tenez compte des points suivants:

UserService {
     UserDto findUser();
}

UserService devrait être correct s'il est utilisé dans le contrôleur où j'ai juste besoin de données uniquement pour que dto soit suffisant,

Mais voici le problème si j'ai utilisé ce service dans un autre service, disons par exemple CustomerService J'ai besoin du modèle lui-même l'objet User car le modèle doit être géré par un contexte de persistance

par exemple

CustomerService {
     void addCustomer() {
           Customer customer = new Customer();
           User user = userService.fimndUser(xxx); // BAM compilation fails since findUser returns UserDto not User
           customer.setUser(user);
     }
} 

Quelles seraient les meilleures pratiques ici si je devais 2 copies de la méthode findUser avec 2 types de retour différents ou 2 copies de UserService classe un pour l'utilisation du contrôleur et d'autres pour le service ou l'utilisation du package de base, ou devrais-je implémenter un modèle de proxy

2
YouYou

Une règle d'or très simple est que vous ne devez utiliser un objet DTO que lorsque vous devez ... transférer des données. Cela signifie utiliser un DTO aux limites de votre API Web ou lorsque vous envoyez l'objet sur un bus de messages. En interne, utilisez simplement vos objets de domaine.

La seule raison pour laquelle un DTO devrait exister est les limitations des couches de (dé) sérialisation. Ceux-ci ont besoin d'objets simples sans logique complexe.

Recommandation:

  • Utilisez des modèles standard dans vos services
  • Convertissez le modèle en DTO dans le contrôleur (c'est-à-dire dans votre application Web) juste avant la sérialisation.
  • Si vous utilisez la messagerie asynchrone, convertissez le modèle en DTO juste avant de pousser le DTO dans la file d'attente de messages

Cela vous permet d'utiliser vos services comme vous le souhaitez et d'enregistrer les DTO lorsqu'ils sont réellement nécessaires.

9
Berin Loritsch