所以,我正在建立一个管理联系人的系统。我的联系域模型有很多字符串属性,以及布尔值。本着保持域模型内部行为的精神,我走上了创建“更新方法”的道路。我开始觉得它有点累赘。在过去,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();
}
}
答案 0 :(得分:1)
首先,并非所有应用程序都适合DDD方法。如果你说你的应用程序之前几乎已经以CRUDish的方式实现了,那么它现在可能仍然是CRUD。不要试图在任何应用程序上应用DDD,因为它是闪亮的新东西。
话虽如此,你不只是为了它的乐趣而编写“更新方法”。他们必须反映您的用户想要执行的域tasks。为什么用户想要更新联系人?联系人已移动或只是更改了电话号码?改变了婚姻状况和姓名?公司的联系人是否已被另一名员工接管?
通常,您不会为给定实体提供大量更新方法。始终有一种方法可以对对域有意义的操作进行分组更改。强迫自己这样做的好方法是:
考虑可以合理地向用户显示的表单字段的最大数量。难道你不能将那个复杂的UI拆分成更小,更有意义的屏幕吗?从那里你必须开始推理(最好是在领域专家的帮助下)关于这些应该反映的任务。
从外面制作your entity fields immutable。因此,你必须更加思考他们的真实本质 - 构造函数应该是什么?其他一些操纵方法应该是什么?