DDD会导致很多添加/更改方法和构造函数重载吗?

我上课了:

public class Person { public string FirstName { get; private set; } public string LastName { get; private set; } public string Email { get; private set; } public string Telephone { get; private set; } public Address Address { get; private set; } public Person(string firstName, string lastName) { //do null-checks FirstName = firstName; LastName = lastName; Address = new Address(); } public void AddOrChangeEmail(string email) { //Check if e-mail is a valid e-mail here Email = email; } public void AddOrChangeTelephone(string telephone) { //Check if thelephone has correct format and valid symbols Telephone = telephone; } public void AddOrChangeAdress(Address address) { Address = address; } 

不在构造函数中的属性是可选的,即该人不需要电子邮件,地址或电话。 但是,我希望为类的用户提供创建对象的机会,而无需先提供所需的信息,然后必须找出用于添加信息的方法。

问题:

  1. 是否可以创建3个额外的重载来为它们提供选项?
  2. 我应该在可选属性上允许公共setter并在那里进行validation吗?
  3. 如果此人结婚并更改姓氏,我是否需要其他方法来更改姓氏,或者我是否应该公开此setter,并且只需要在构造函数中使用它们?

  1. 没有。
  2. 把它公之于众。

假设您将在AddOrChange方法中有更多代码,例如格式化逻辑或validation,那么我将执行以下操作。 否则,我完全摆脱了AddOrChange方法:

 public class Person { private string _email = string.empty; private string _telephone = string.empty; private Address _address = new Address(); public string FirstName { get; set; } public string LastName { get; set; } public string Email { get { return _email } set { AddOrChangeEmail(value); } } public string Telephone { get { return _telephone;} set { AddOrChangeTelephone(value); } } public Address Address { get { return _address; } set { AddOrChangeAddress(value); } } public Person(string firstName, string lastName) { //do null-checks FirstName = firstName; LastName = lastName; } private void AddOrChangeEmail(string email) { //Check if e-mail is a valid e-mail here _email = email; } private void AddOrChangeTelephone(string telephone) { //Check if thelephone has correct format and valid symbols _telephone = telephone; } private void AddOrChangeAddress(Address address) { _address = address; } } 

要使用此类,您可以执行以下任何操作:

 Person p = new Person("Tom", "Jones"); p.Telephone = "9995551111"; 

要么

 Person p = new Person("Tom", "Jones") { Telephone = "9995551111", Email="spamme@ms.com" } 

AddOrChange相当于带有public setter的简单属性,因此您不需要这些方法。

 public class Person { public string FirstName { get; private set; } public string LastName { get; private set; } public Email Email { get; set; } public Telephone Telephone { get; set; } public Address Address { get; set; } public Person(string firstName, string lastName) { //do null-checks FirstName = firstName; LastName = lastName; } } 
  1. 如果用户在创建人员期间想要在所需数据旁边提供其他内容,则可以使用类初始值设定项。 您还可以向构造函数添加一些可选参数。

    var bob = new Person("Bob", "Uncle") { Address = someAddress };

  2. 如果可以让人重新安置,那么为什么不使用公共设置器来更改地址呢? 当然,您应该检查地址是否有效。 此外,如果重新定位是一个业务流程(即您正在重新安置酒店的某个人),那么在域服务上进行此操作会很好(这将validation目的地房间是否为空并准备就绪)。

  3. 允许更改名称是可以的。 通常名称不是这些实体的身份,因此它可能会改变。

此外,我还介绍了电子邮件和电话的价值对象。 我认为validation电子邮件地址是否有效并非由此负责。 将其移至电子邮件类。 与电话和地址相同。

DDD会导致很多添加/更改方法和构造函数重载吗?

不,许多更新方法不是DDD的结果。

您的Person类可以重写为只有2种更新方法:

 class Person public function Rename(FirstName as Name, LastName as Name) as Person public function ChangeContacts( Address as Maybe(of Address), Phone as Maybe(of Phone), Mail as Maybe(of MailAddress)) as Person end class 

Rename方法接受两个特殊Name类型的必需参数。 名称的validation检查在创建名称时发生,而不是在将它们传递到Person类时。

ChangeContacts方法接受三个可选参数,其中任何参数都可以不存在。 特殊Maybe类型表示它们是可选的。 特殊AddressPhoneMailAddress Address类型表示这些参数已经有效,并且不需要在Person类中再次validation它们。

用例

人结婚并更改姓氏

 Person = Person. Rename(Person.FirstName, LastNameAfterMarriage) 

人购买新的电话号码

 Person = Person. ChangeContacts(Person.Address, NewPhoneNumber, Person.Mail) 

人失去了电话号码

 Dim NewPhoneNumber = Maybe.Create(Nothing) Person = Person. ChangeContacts(Person.Address, NewPhoneNumber, Person.Mail) 

模式是使用旧值+一些新值调用更新方法。