DDD服务方法粒度

时间:2015-02-19 05:21:19

标签: domain-driven-design

所以,我正在建立一个管理联系人的系统。我的联系域模型有很多字符串属性,以及布尔值。本着保持域模型内部行为的精神,我走上了创建“更新方法”的道路。我开始觉得它有点累赘。在过去,CRUD应用程序只有一个更新方法,它会一次性设置所有属性。

我是在正确的道路上吗?我担心在我的域服务和域实体上有10到15种更新方法。

仅供参考,给出的示例有点人为,所以想象一下具有大量字符串和布尔属性的模型。

 // Application Layer Stuff
 public class UpdateContactCommand
 {
      public UpdateNamePredicate UpdateName { get; set; }
      public UpdatePhonePredicate UpdatePhone { get; set; }
      public int ContactId { get; set; }
 }

 public class UpdateNamePredicate
 {
      public string NewFirstName { get; set; }
      public string NewLastName { get; set; }
 }
 public class UpdatePhonePredicate
 {
      public string NewPHone { get; set; }

 }

 public class UpdateContactResponse
 {
      public bool Success { get; set; }
      public string Message { get; set; }
 }

 public interface IWcfService
 {
      UpdateContactResponse UpdateContact(UpdateContactCommand updateContactCommand);
 }

 public class WcfService : IWcfService
 {
      private readonly IContactService _contactService;

      public WcfService(IContactService contactService)
      {
           _contactService = contactService;
      }

      public UpdateContactResponse UpdateContact(UpdateContactCommand updateContactCommand)
      {
           if (updateContactCommand.UpdateName != null)
           {
                _contactService.UpdateName(updateContactCommand.ContactId, updateContactCommand.UpdateName.NewFirstName,
                     updateContactCommand.UpdateName.NewLastName);
           }

           if (updateContactCommand.UpdatePhone != null)
           {
                _contactService.UpdatePhone(updateContactCommand.ContactId, updateContactCommand.UpdatePhone.NewPHone);
           }

           return new UpdateContactResponse();
      }
 }



 // Domain Layer
 public interface IContactService
 {
      // There are lots more of these
      void UpdateName(int contactId, string newFirstName, string newLastName);
      void UpdatePhone(int contactId, string newPhone);
 }


 public class ContactService : IContactService
 {
      private readonly IContactRepository _contactRepository;

      public ContactService(IContactRepository contactRepository)
      {
           _contactRepository = contactRepository;
      }

      public void UpdateName(int contactId, string newFirstName, string newLastName)
      {
           var contact = _contactRepository.GetById(contactId);

           contact.SetName(newFirstName, newLastName);

           _contactRepository.Commit();
      }

      public void UpdatePhone(int contactId, string newPhone)
      {
           var contact = _contactRepository.GetById(contactId);

           contact.SetPhone(newPhone);

           _contactRepository.Commit();
      }
 }

 public interface IContact
 {
      int Id { get; set; }

     // There are lots more of these
      void SetName(string newFirstName, string newLastName);
      void SetPhone(string newPhone);
 }

 public class Contact : IContact
 {
      public int Id { get; set; }
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public string Phone { get; set; }
      public void SetName(string newFirstName, string newLastName)
      {
           FirstName = newFirstName;
           LastName = newLastName;
      }

      public void SetPhone(string newPhone)
      {
           Phone = newPhone;
      }
 }

 public interface IContactRepository
 {
      IContact GetById(int id);
      void Commit();
 }

 public class ContactRepository : IContactRepository
 {
      public IContact GetById(int id)
      {
           // Not important
           throw new NotImplementedException();
      }

      public void Commit()
      {
          // Not important
           throw new NotImplementedException();
      }
 }

1 个答案:

答案 0 :(得分:1)

首先,并非所有应用程序都适合DDD方法。如果你说你的应用程序之前几乎已经以CRUDish的方式实现了,那么它现在可能仍然是CRUD。不要试图在任何应用程序上应用DDD,因为它是闪亮的新东西。

话虽如此,你不只是为了它的乐趣而编写“更新方法”。他们必须反映您的用户想要执行的域tasks。为什么用户想要更新联系人?联系人已移动或只是更改了电话号码?改变了婚姻状况和姓名?公司的联系人是否已被另一名员工接管?

通常,您不会为给定实体提供大量更新方法。始终有一种方法可以对对域有意义的操作进行分组更改。强迫自己这样做的好方法是:

  • 考虑可以合理地向用户显示的表单字段的最大数量。难道你不能将那个复杂的UI拆分成更小,更有意义的屏幕吗?从那里你必须开始推理(最好是在领域专家的帮助下)关于这些应该反映的任务。

  • 从外面制作your entity fields immutable。因此,你必须更加思考他们的真实本质 - 构造函数应该是什么?其他一些操纵方法应该是什么?