Je travaille sur une application web standard avec un domaine organisé autour de concepts DDD. Je me demande quel genre d'objets mes services d'application devraient accepter et retourner. Disons que j'ai un service d'application pour User
agrégat.Paramètres de service d'application/types de retour
1) DTO/types simples (string, int, etc.)
public interface UserApplicationService {
void registerUser(UserDTO userDTO);
List<UserDTO> getUsersForOrganization(String organizationId);
}
Dans ce cas, le service d'application est chargé d'appeler l'assembleur transformer DTO aux objets de domaine et l'inverse.
L'avantage de cette approche est que mon service d'application est une limite claire pour mes objets de domaine. Un autre est que le service d'application est une frontière de transaction claire. Les objets de domaine gérés par le contexte de persistance ne fuient pas en dehors de la transaction. Inconvénient: dans le cas de formulaires, la validation doit être basée sur DTO. Donc, mes règles de validation sont dupliquées entre le domaine (l'objet est responsable de son état) et les règles de validation DTO. (Comme dans le cas de Spring MVC sample application). Aussi, si certaines parties de la vue nécessitent une autre forme de modèle (disons que UserDTO n'a pas assez d'informations pour que la vue soit rendue), je vais devoir créer un autre DTO et une base sur deux DTO retournés par le service d'application. , utilisé par vue.
2) types de domaine
public interface UserApplicationService {
void registerUser(User user);
List<User> getUsersForOrganization(OrganizationId organizationId);
}
Dans ce cas, le contrôleur/présentateur est responsable de la transformation.
Gros inconvénient est que mes objets de domaine fuient du service d'application - pas de séparation claire. En outre, où sont nos limites de transaction? Les objets de domaine qui peuvent être liés à, par exemple, la session Hibernate, fuient en dehors de la couche des services d'application. (Cependant, j'ai remarqué que c'est le nombre d'applications exemples qui sont écrites.)
L'avantage est que le contrôleur/présentateur est responsable de la préparation du modèle pour la vue, de sorte qu'il peut composer des bases de DTO sur les exigences de vue. Par exemple, view peut nécessiter des informations supplémentaires qui ne sont pas renvoyées dans DTO à partir de #getUsersForOrganizationMethod. En outre, la validation peut être basée sur des objets de domaine, elle n'est donc pas dupliquée entre les objets DTO et les objets de domaine.
3) objets de domaine + façade
Cette troisième option est utilisé dans DDDsample application. Les services d'application renvoient des types de domaine, mais une certaine facade est responsable de la transformation. Donc dans mon cas, le contrôleur/présentateur parle de la façade avec les DTO, la façade fait la transformation et parle avec les services de l'application en utilisant les objets du domaine. Cependant, à mon humble avis, il semble un peu écrasant - trop de couches, trop de code standard. Pour un service d'application, cela peut sembler bien, mais si nous en avions des dizaines, nous devions avoir le même nombre de méthodes de façade - une duplication pure. De plus, où sont les limites de transaction?
Belle réponse, merci! Couple de commentaires: 1) si vous acceptez la VO dans les services applicatifs, quel serait votre type de paramètre en cas d'opération tel que le paiement? Il y a deux ou trois produits que vous aimeriez passer dans une invocation de méthode, et vous aurez besoin d'un agrégat pour chacun d'eux - voici les DTO à mon humble avis; Je pense que le bean formulaire appartient à la couche de présentation et ne devrait pas être accepté par le service. 2) Où sont vos limites de transaction? Si nous renvoyons des entités à partir de services, cela permettrait au contrôleur de le modifier et potentiellement conduire à des problèmes étranges (en particulier si l'entité est un proxy transactionnel). –
@ woof-woof quelques mises à jour et je ne comprends pas tout le "checkout" et "produits", pourriez-vous expliquer un peu plus? – Hippoom
Disons que vous avez une application de magasin et que l'utilisateur veut acheter un certain nombre de produits A et de produits B. L'utilisateur effectue donc une extraction (c'est ma compréhension :)). L'utilisateur veut acheter tout ou rien - c'est pourquoi nous aurons besoin d'un objet pour agréger les objets et leur quantité. –