Should I ignore the guidance and avoid putting validation in the command objects?

妖精的绣舞 提交于 2019-12-11 05:59:50

问题


I am using CQRS. Everywhere I read tells me to put validation logic in the command objects. For example, see this link: https://lostechies.com/jimmybogard/2016/04/29/validation-inside-or-outside-entities/

Please see the command below (taken from the link):

public class ChangeNameCommand { 
   [Required] 
   public string FirstName { get; set; } 
   [Required] 
   public string LastName { get; set; } 
 } 

and the Business Object below (also taken from the link - note that I have changed the the parameter passed to the Customer constructor from a class to an interface):

public class Customer 
{ 
   public string FirstName { get; private set; } 
   public string LastName { get; private set; } 

   public void ChangeName(IChangeNameCommand command) { 
     FirstName = command.FirstName; 
     LastName = command.LastName; 
   } 
 } 

In my case the commands are stored in one class library and the business objects in others (because the commands are shared by multiple microservice type projects). If I follow the guidance (and put the validation in the commands) then I believe there is nothing to stop a developer doing this:

public class ChangeNameCommandWithoutValidation : IChangeNameCommand { 
   public string FirstName { get; set; } 
   public string LastName { get; set; } 
 } 

and then passing the command (without the validation) to the domain object. In this case I believe the Domain Object has no control what is passed to it?

Therefore should I be going against all of the guidance I can find and do the validation in the domain object? I believe I should do this because the commands are in a separate class library to the domain objects. Have I understood this correctly?

I believe this question is also relevant when passing an event to the customer domain object (when using event sourcing).


回答1:


A few thoughts:

  • The blog post you linked to is confusing because it equates validation with invariants.

    In DDD literature, invariants refer most of the time to domain rules that are enforced in the root entity and nowhere else. Regarding this domain validity, not "all of the guidance", as you put it, is for enforcing them on the command side - much the contrary. Popular schools of thought consider that an entity should always be valid and therefore should take care of its own rules (aka invariants).

    The kind of validity that the samples in Jimmy Bogard's post speak to, on the other hand, is on the borderline between domain validity and user input validity. I wouldn't make it a stone-set rule to put that kind of validation on one side or the other. While it's legitimate to consider that it's really a job for the Command, with some typesystems you can perfectly encode that kind of non-null constraints in the entity property types and it would be a shame not to take advantage of that free extra correctness.

  • As has been said in the comments, putting an interface on top of a command seems strange.

  • Thinking about what could happen if someone subclassed the command in a malicious way is probably pointlessly defensive. Within a team, you have total control over what is implemented and I can't think of a good reason for "command programmers" to be on a different team than "entity programmers".



来源:https://stackoverflow.com/questions/50759872/should-i-ignore-the-guidance-and-avoid-putting-validation-in-the-command-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!