Is lots of add/change methods and constructor overloads a consequence of DDD?

梦想的初衷 提交于 2019-12-06 15:49:18
  1. No.
  2. Yes
  3. Make it public.

Assuming you are going to have more code in the AddOrChange methods such as formatting logic or validation then I'd do the following. Otherwise, I'd completely get rid of the AddOrChange methods:

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;
    }
}

To work with this class you could do any of the following:

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

or

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

AddOrChange is equivalent to simple property with public setter, thus you don't need those methods.

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. If user during person creation want to provide something additional beside required data, she can use class initializers. Also you can add some optional parameters to constructor.

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

  2. If its OK for person to relocate, then why not to use public setter for changing address? Of course, you should check if address is valid. Also if relocating is a business process (i.e. you are relocating someone in hotel) then it would be nice to have this operation on domain service (which will verify if destination room is empty and ready).

  3. Allowing to change name is OK. Usually name is not identity for such entities, thus it could change.

Also, I'd introduced value objects for email and telephone. I think it is not person's responsibility to verify if email address valid. Move that to Email class. Same with Phone and Address.

Is lots of add/change methods and constructor overloads a consequence of DDD?

No, lots of updating methods is not consequence of DDD.

Code

Your Person class can be rewritten to have only 2 updating methods:

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 method accepts two required parameters of special Name type. Validation checks for names happen when names are created, not when they are passed into Person class.

ChangeContacts method accepts three optional parameters any of which can be absent. Special Maybe type indicates that they are optional. Special Address, Phone and MailAddress types indicate that these parameters are already valid and there is no need to validate them again in Person class.

Use case

Person marries and changes last name

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

Person buys new phone number

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

Person lost phone number

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

The pattern is to call updating method with old values + some new values.

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