348 votes

Conception pilotée par le domaine : Service de domaine, service d'application

Quelqu'un peut-il expliquer la différence entre les services de domaine et d'application en fournissant quelques exemples ? Et, si un service est un service de domaine, dois-je placer l'implémentation réelle de ce service dans l'assemblage de domaine et, si oui, dois-je également injecter des référentiels dans ce service de domaine ? Des informations seraient vraiment utiles.

476voto

Vijay Patel Points 5696

Les services existent en trois versions : Services du domaine , Services d'application et Services d'infrastructure .

  • Services du domaine : Encapsule logique d'entreprise qui n'est pas naturellement dans un objet du domaine, et sont PAS les opérations CRUD typiques, qui relèveraient d'une Référentiel .
  • Services d'application : Utilisé par consommateurs externes pour parler à votre système (pensez Services Web ). Si les consommateurs ont besoin d'accéder aux opérations CRUD, elles seront exposées ici.
  • Services d'infrastructure : Utilisé pour abstraire les préoccupations techniques (par ex. MSMQ, fournisseur de courrier électronique, etc).

Il est judicieux de conserver les services de domaine avec vos objets de domaine, car ils sont tous axés sur la logique du domaine. Et oui, vous pouvez injecter des référentiels dans vos services.

Les services d'application utilisent généralement les deux services de domaine et Référentiels pour traiter les demandes externes.

J'espère que cela vous aidera !

6 votes

Où placeriez-vous les commandes et les requêtes du CQRS ? Quel service les génère et quel service les traite ?

15 votes

Je pense que les services d'application devraient être indépendants des détails techniques comme les "services web", ils sont utilisés par ces services. Voir Services de conception pilotée par le domaine

1 votes

@prograhammer - Un exemple de service de domaine pourrait être FundsTransferService, où le modèle de domaine est un BankAccount, le transfert pourrait avoir une logique commerciale qui ne correspond pas directement à un objet de compte (tiré du livre Evans DDD).

135voto

Niels van der Rest Points 11802

(Si vous n'avez pas envie de lire, il y a un résumé en bas de page :-)

J'ai moi aussi eu du mal à définir précisément les services d'application. Bien que la réponse de Vijay ait été très utile à mon processus de réflexion il y a un mois, j'en suis venu à ne pas être d'accord avec une partie de celle-ci.

Autres ressources

Il y a très peu d'informations sur les services d'application. Des sujets tels que les racines d'agrégats, les référentiels et les services de domaine sont largement abordés, mais les services d'application ne sont que brièvement mentionnés ou carrément ignorés.

L'article du magazine MSDN Une introduction à la conception pilotée par le domaine décrit les services d'application comme un moyen de transformer et/ou d'exposer votre modèle de domaine à des clients externes, par exemple comme un service WCF. C'est ainsi que Vijay décrit également les services d'application. De ce point de vue, les services d'applications sont une l'interface de votre domaine .

Les articles de Jeffrey Palermo sur l'architecture de l'oignon (partie un , deux et trois ) sont une bonne lecture. Il traite les services d'application comme concepts au niveau des applications comme la session d'un utilisateur. Bien que cela soit plus proche de ma compréhension des services d'application, ce n'est toujours pas conforme à mes idées sur le sujet.

Mes réflexions

J'en suis venu à considérer les services d'application comme les dépendances fournies par l'application . Dans ce cas, l'application peut être une application de bureau ou un service WCF.

Domaine

Il est temps de donner un exemple. Vous commencez avec votre domaine. Toutes les entités et tous les services du domaine qui ne dépendent pas de ressources externes sont implémentés ici. Tous les concepts de domaine qui dépendent de ressources externes sont définis par une interface. Voici un exemple de solution possible (le nom du projet est en gras) :

My Solution
- **My.Product.Core** (My.Product.dll)
  - DomainServices
      IExchangeRateService
    Product
    ProductFactory
    IProductRepository

Le site Product et ProductFactory ont été implémentées dans l'assemblage de base. Le site IProductRepository est quelque chose qui est probablement soutenu par une base de données. L'implémentation de celle-ci ne concerne pas le domaine et est donc définie par une interface.

Pour l'instant, nous allons nous concentrer sur le IExchangeRateService . La logique commerciale de ce service est mise en œuvre par un service web externe. Cependant, son concept fait toujours partie du domaine et est représenté par cette interface.

Infrastructure

La mise en œuvre des dépendances externes fait partie de l'infrastructure de l'application :

My Solution
+ **My.Product.Core** (My.Product.dll)
- **My.Product.Infrastructure** (My.Product.Infrastructure.dll)
  - DomainServices
      XEExchangeRateService
    SqlServerProductRepository

XEExchangeRateService met en œuvre la IExchangeRateService service de domaine en communiquant avec xe.com . Cette mise en œuvre peut être utilisée par vos applications qui utilisent votre modèle de domaine, en incluant l'assemblage d'infrastructure.

Application

Notez que je n'ai pas encore mentionné les services d'application. Nous allons les examiner maintenant. Disons que nous voulons fournir un IExchangeRateService qui utilise un cache pour accélérer les recherches. Le schéma de cette classe décorateur pourrait ressembler à ceci.

public class CachingExchangeRateService : IExchangeRateService
{
    private IExchangeRateService service;
    private ICache cache;

    public CachingExchangeRateService(IExchangeRateService service, ICache cache)
    {
        this.service = service;
        this.cache = cache;
    }

    // Implementation that utilizes the provided service and cache.
}

Remarquez le ICache paramètre ? Ce concept ne fait pas partie de notre domaine, il ne s'agit donc pas d'un service du domaine. Il s'agit d'un service des applications . C'est une dépendance de notre infrastructure qui peut être fournie par l'application. Présentons une application qui en fait la démonstration :

My Solution
- **My.Product.Core** (My.Product.dll)
  - DomainServices
      IExchangeRateService
    Product
    ProductFactory
    IProductRepository
- **My.Product.Infrastructure** (My.Product.Infrastructure.dll)
  - ApplicationServices
      ICache
  - DomainServices
      CachingExchangeRateService
      XEExchangeRateService
    SqlServerProductRepository
- **My.Product.WcfService** (My.Product.WcfService.dll)
  - ApplicationServices
      MemcachedCache
    IMyWcfService.cs
  + MyWcfService.svc
  + Web.config

Tout cela se retrouve dans l'application comme ceci :

// Set up all the dependencies and register them in the IoC container.
var service = new XEExchangeRateService();
var cache = new MemcachedCache();
var cachingService = new CachingExchangeRateService(service, cache);

ServiceLocator.For<IExchangeRateService>().Use(cachingService);

Résumé

Une application complète se compose de trois couches principales :

  • domaine
  • infrastructure
  • application

La couche domaine contient les entités du domaine et les services autonomes du domaine. Tout domaine concepts (cela inclut les services de domaine, mais aussi les référentiels) qui dépendent de ressources externes, sont définis par des interfaces.

La couche infrastructure contient l'implémentation des interfaces de la couche domaine. Ces implémentations peuvent introduire de nouvelles non-domaine les dépendances qui doivent être fournies à l'application. Ce sont les services de l'application et ils sont représentés par des interfaces.

La couche application contient la mise en œuvre des services d'application. La couche application peut également contenir des implémentations supplémentaires des interfaces de domaine, si les implémentations fournies par la couche infrastructure ne sont pas suffisantes.

Bien que ce point de vue ne corresponde pas à la définition DDD générale des services, il sépare le domaine de l'application et permet de partager l'ensemble du domaine (et de l'infrastructure) entre plusieurs applications.

0 votes

Merci d'avoir partagé vos réflexions, mais j'ai une question. Comment créer un IDomainService dont une méthode prend les données du contrôleur (MVC) ? Supposons que nous ayons la méthode Save(RequestModel model) du contrôleur. RequestModel appartient à l'interface utilisateur plutôt qu'à la couche de domaine. Comment dois-je transmettre les données à notre service ? Je ne peux pas faire IDomainService.Save(model).

3 votes

@dario-g : Il faudrait reconstruire/repeupler votre modèle de domaine à partir du modèle de requête et passer le modèle de domaine au service de domaine. Cette question peut vous donner quelques idées. Sinon, faites-le moi savoir et je verrai si j'ai le temps d'ajouter une réponse à l'autre question.

0 votes

La question proposée n'est pas très bonne. Très souvent, vous devez effectuer une action sur un objet du domaine. Il ne s'agit pas simplement de copier des valeurs d'un objet à l'autre. Pire encore quand vous devez le faire sur certains objets de domaine différents et pas un seul. Donc, je suis impatient... Jetez un oeil là-dessus : lostechies.com/blogs/jimmy_bogard/archive/2009/09/17/

57voto

Ghola Points 161

La meilleure ressource qui m'a aidé à comprendre la différence entre un service d'application et un service de domaine est l'implémentation Java de l'exemple de chargement d'Eric Evans, qui se trouve à l'adresse suivante ici . Si vous ne le téléchargez pas, vous pouvez vérifier l'intérieur du RoutingService (un service de domaine) et du BookingService, CargoInspectionService (qui sont des services d'application).

Mon moment "aha" a été déclenché par deux choses :

  • En lisant la description des services dans le lien ci-dessus, plus précisément cette phrase :

    Les services de domaine sont exprimés en termes de langage omniprésent et de les types de domaine, c'est-à-dire que les arguments de la méthode et les valeurs de retour sont des classes de domaine appropriées.

  • En lisant ceci article de blog surtout cette partie :

    Ce que je trouve très utile pour séparer les pommes des oranges, c'est c'est de penser en termes de flux de travail de l'application. Toute la logique concernant l'application le flux de travail de l'application finit généralement par être des services d'application intégrés dans la couche d'application, tandis que les concepts du domaine qui ne semblent pas convenir en tant qu'objets de modèle finissent par former un ou plusieurs services de domaine. Services de domaine.

4 votes

Je suis d'accord, c'est exactement la façon dont je définis les services d'application, et cela correspond à toutes les situations que j'ai rencontrées jusqu'à présent. Les services de domaine traitent de tout ce qui est lié aux objets du domaine, mais qui dépasse le cadre d'une seule entité. Ex : BookReferencesService.GetNextAvailableUniqueTrackingNumber(), l'accent est clairement mis sur les règles de gestion*. En ce qui concerne le service d'application, c'est exactement ce que vous décrivez, la plupart du temps je commence par mettre ce workflow métier dans mes actions de contrôleur, et quand je le remarque je refacture cette logique dans la couche de service d'application. Nous pourrions dire que cette couche est pour les cas d'utilisation

1 votes

*Et ces interfaces de service de domaine sont consommées par les entités du domaine.

1 votes

Le lien vers l'article du blog est cassé. Quelqu'un a-t-il pu en trouver un qui fonctionne ?

52voto

Timo Points 560

D'après le livre rouge (Implementing Domain Driven Design, par Vaughn Vernon), c'est ainsi que je comprends les concepts :

Objets du domaine ( entités et objets de valeur ) encapsulent le comportement requis par le (sous-)domaine, le rendant naturel, expressif et compréhensible.

Services de domaine encapsuler les comportements qui ne s'intègrent pas dans un système de gestion de l'information. simple objet du domaine. Par exemple, une bibliothèque de livres prêtant un Book à un Client (avec des Inventory ) pourrait le faire à partir d'un service de domaine.

Services d'application gérer le flux des cas d'utilisation, y compris toute préoccupation supplémentaire nécessaire sur le dessus de celui du domaine. Il expose souvent de telles méthodes par le biais de son API, pour que les clients externes puissent les utiliser. Dans le prolongement de notre exemple précédent, notre service d'application pourrait exposer une méthode LendBookToClient(Guid bookGuid, Guid clientGuid) que :

  • Récupère le Client .
  • Confirme ses permissions. ( Notez comment nous avons gardé notre modèle de domaine libre de tout souci de sécurité ou de gestion des utilisateurs. Une telle pollution pourrait entraîner de nombreux problèmes. Au lieu de cela, nous remplissons cette exigence technique ici, dans notre service d'application. )
  • Récupère le Book .
  • Appelle le service de domaine (en passant l'adresse Client et Book ) pour gérer les logique réelle du domaine de prêter le livre au client. Par exemple, j'imagine que la confirmation de la disponibilité du livre fait partie intégrante de la logique du domaine.

Un service d'application doit généralement avoir un flux très simple. Des flux de services d'application complexes indiquent souvent que la logique du domaine s'est échappée du domaine.

Comme vous pouvez, je l'espère, le voir, le modèle de domaine reste très nettoyer De cette façon, il est facile à comprendre et à discuter avec les experts du domaine, car il ne contient que ses propres préoccupations commerciales réelles. Le site flux des demandes d'autre part, est également beaucoup plus facile à gérer, car elle est libérée des préoccupations liées au domaine et devient concise et directe.

47voto

kboom Points 93

Service des domaines est l'extension du domaine. Il ne doit être vu que dans le contexte du domaine. Il ne s'agit pas d'une action de l'utilisateur comme par exemple fermer le compte ou quelque chose comme ça. Le service de domaine convient lorsqu'il n'y a pas d'état. Sinon, ce serait un objet de domaine. Le service de domaine fait quelque chose qui n'a de sens que lorsqu'il est fait avec d'autres collaborateurs (objets de domaine ou autres services). Et cela le sens est la responsabilité d'une autre couche.

Service d'application est la couche qui initialise et supervise l'interaction entre les objets et les services du domaine. Le flux est généralement le suivant : récupérer l'objet (ou les objets) du domaine dans le référentiel, exécuter une action et le(s) remettre en place (ou non). Il peut faire plus - par exemple, il peut vérifier si un objet de domaine existe ou non et lancer des exceptions en conséquence. Il permet donc à l'utilisateur d'interagir avec l'application (et c'est probablement de là que vient son nom) - en manipulant les objets et services du domaine. Les services d'application doivent généralement représenter toutes les possibilités cas d'utilisation . La meilleure chose que vous puissiez faire avant de penser au domaine est probablement de créer des interfaces de service d'application qui vous donneront une bien meilleure idée de ce que vous essayez réellement de faire. En ayant cette connaissance, vous pourrez vous concentrer sur le domaine.

Les référentiels peuvent généralement être injectés dans les services de domaine, mais c'est un scénario plutôt rare. C'est la couche applicative qui le fait la plupart du temps.

16 votes

" Le service de domaine s'adapte là où il n'y a pas d'état. Sinon, il s'agirait d'un objet de domaine", ce qui m'a permis de comprendre. Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X