2009-09-08 5 views
5

Je lisais Pro ASP.NET MVC Framework, Steven Sanderson, et au chapitre 11, il traite de la validation des données.Validation des règles sur la couche de données ou de domaine?

À la page 390, nous voyons la section Déplacement de validation de logique dans votre modèle couche. Dans cette section, nous voyons, à la page 392, du code montrant comment implémenter la validation.

Le code implémente une méthode GetRuleViolations() et la méthode Save() l'utilise pour lancer un RuleException si quelque chose n'allait pas.

Il semble à moi, cependant, qu'il n'y a pas de distinction entre la couche de domaine et un accès aux données couche, voici le code:

public void Save() { 
    var errors = GetRuleViolations(); 
    if (errors.Count > 0) 
     throw new RuleException(errors); 

    // Todo: Now actually save to the database or whatever 
} 
private NameValueCollection GetRuleViolations() { 
    // validations... 
} 

Dans un projet, je travaille, j'ai Couche de domaine, aussi ignorante que possible pour la persistance, et couche d'accès aux données, implémentant l'accès aux données via NHibernate et implémentant les référentiels dont les interfaces ont été définies dans la couche Domaine. Si j'implémente les règles de validation que l'auteur propose ici, sur la méthode "Save()", elles iraient sur ma couche d'accès aux données, même si, du moins je pense, elles devraient résider sur le modèle de domaine!

Alors, ma question est: lors de la création d'une l'application en couches, avec une couche de domaine mise en œuvre des entités de domaine et d'exposer les interfaces aux référentiels (persistance ignorants), une données couche d'accès aux mise en œuvre des référentiels de la couche de domaine et l'implémentation de tout le code d'accès aux données, où les règles de validation doivent-elles se trouver?

Mon interface primaire (ou au moins première) sera une application ASP.NET MVC, si cela peut changer quelque chose.

Merci.

+0

En fait, j'ai deux idées divergentes qui me trottent dans la tête: (1) si je décide d'écrire une nouvelle LDA, je ne voudrais pas réécrire toutes les mêmes règles (DRY) - pour éviter de manquer une règle une erreur ou devoir ré-implémenter toutes les nouvelles règles plusieurs fois; et (2) il serait difficile d'implémenter une «validation contextuelle» sur le domaine (puisque je devrais injecter des détails sur le contexte du domaine chaque fois que je le traite) ... –

Répondre

2

Dans une architecture MVC, le M (modèle) comprend deux la couche de domaine et couche d'accès aux données. Donc, il n'y a rien de mal avec l'exemple de Sanderson. Cela dit, lorsque vous implémentez votre modèle de domaine en utilisant ces deux couches (au lieu d'en avoir une seule), la logique de validation doit aller à la couche domaine pour augmenter la cohésion des objets du domaine et éviter la duplication de la logique de validation par exemple dans chaque référentiel concret).

+1

Je suis d'accord, mais qu'en est-il de la "validation contextuelle"? Par exemple, les objets de domaine sont valides, ils sont prêts à être persistants, MAIS il y a une règle qui dit si une voiture rouge est visible à travers la fenêtre de l'utilisateur, alors il n'est pas autorisé à enregistrer l'objet. Cette règle contient des informations contextuelles sur le lieu/l'heure de l'opération * saving *. Cette information proviendrait d'un service qui donne une liste de toutes les voitures garées à proximité (c.-à-d. Quelque chose qui n'est pas dans votre projet). Où cette règle de validation serait-elle appliquée, tout en respectant un principe DRY? –

+0

Dans la méthode du service qui effectue l'enregistrement. J'ai généralement ces couches dans mes applications ASP.NET MVC: Controller -> Service -> Repository. Les objets de domaine sont utilisés à travers ces couches. Le service (pas le contrôleur) doit déclencher la validation dans les objets de domaine. La validation contextuelle est ensuite effectuée par le service avant, par exemple en sauvegardant les objets du domaine. Toutes ces choses (par exemple, Service, Référentiel, et objets de domaine, c'est-à-dire Entité) sont des concepts de conception pilotée par domaine. Pourquoi DRY? Par exemple. Vous pouvez réutiliser tous ces éléments (Services, Référentiels et Entités) dans une application WebForms sans modification. –

+1

Buu Nguyen: Martin Fowler fait remarquer que «plus vous avez de comportements dans les services, plus vous avez de chances de vous priver des avantages d'un modèle de domaine.Si toute votre logique est dans les services, vous vous êtes volé à l'aveugle " (http://martinfowler.com/bliki/AnemicDomainModel.html) Cela dit, votre modèle est anémique. – BrunoSalvino

1

Ils appartiennent certainement à votre couche de domaine (où l'on pouvait mettre en œuvre IDataErrorInfo, mais ce serait utile que pour Windows Forms ou des applications WPF, je pense). Il semble que cette philosophie de validation soit très similaire à celle exposée par Paul Stovell (consultez this article of his). C'est très puissant et je l'utilise beaucoup. En gros:

  1. Il n'y a rien de mal à avoir un objet métier non valide, tant que vous ne cherchez pas à persister il.
  2. Toutes les règles rompues doivent être récupérées à partir de l'objet métier, afin que la liaison de données, ainsi que votre propre code, puissent voir s'il existe des erreurs et les gérer de manière appropriée.

Ainsi, aussi ignorant que votre couche de domaine est des questions de persistance, je crois que vos entités devraient être au moins au courant quand ils sont persistaient. La méthode Save est un moyen de les rendre responsables de leur propre persistance (qu'ils peuvent ensuite déléguer à un Data Access Layer). Je ne vois rien de mal à ça.

+0

Je ne suis pas d'accord, comme l'écrit Jimmy Nilsson son livre DDD, "Tous les états, même en cas d'erreur, devraient être sauvables". L'exemple qu'il utilise est: "Les utilisateurs détestent apprendre des applications qu'ils ne peuvent pas enregistrer les modifications en cours à cause d'erreurs.Un de mes amis l'a comparé à ne pas être autorisé à enregistrer un document de traitement de texte si vous avez des fautes d'orthographe. – BrunoSalvino

0

Je préfère généralement toujours valide objets de domaine. Les objets de domaine ne peuvent être modifiés que par des méthodes qui empêchent l'objet de devenir invalide. D'autre part, les objets de présentation peuvent contenir des valeurs temporaires non valides ou des valeurs qui ne peuvent pas être analysées correctement. Mais les appels de méthodes ne seront envoyés aux objets de domaine que par la couche de présentation lorsque les données sont valides.

Les objets de domaine imposent des invariants, les objets de présentation indiquent à l'utilisateur comment il doit modifier son entrée pour respecter les contraintes.

0

La validation doit être effectuée dans votre couche de domaine. Votre logique métier fait partie du domaine, pas de l'accès aux données. La validation ne peut pas être effectuée à l'intérieur de l'objet de domaine lui-même (la classe réelle), mais elle doit être à l'intérieur de la couche de domaine.

Questions connexes