Много ли методов добавления/изменения и конструктор перегружает последствия 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;
 }

Свойства, которые не находятся в конструкторе, являются необязательными, то есть человеку не требуется адрес электронной почты, адрес или телефон. Тем не менее, я хочу дать пользователю класса возможность создать объект без необходимости сначала предоставить требуемую информацию, а затем потом узнать, какие методы использовать для добавления информации.

Вопросы:

  • Правильно ли создать 3 дополнительных перегрузки, чтобы дать им эту опцию?
  • Должен ли я разрешать публичным сеттерам дополнительные свойства и выполнять там проверку?
  • Если человек женится и изменит фамилию, мне нужен дополнительный метод для изменения фамилии или я должен сделать этот сеттер общедоступным и просто потребовать их в конструкторе?
3 ответа

  • Нет.
  • Да
  • Сделать общедоступным.

Предполагая, что у вас будет больше кода в методах AddOrChange, таких как логика форматирования или валидация, я бы сделал следующее. В противном случае я полностью избавился бы от методов 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="[removed_email]" }


AddOrChange эквивалентно простому свойству с открытым сетевым устройством, поэтому вам не нужны эти методы.

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;
 }
}
  • Если пользователь во время создания человека хочет предоставить что-то дополнительно помимо требуемых данных, она может использовать инициализаторы классов. Также вы можете добавить некоторые дополнительные параметры в конструктор.

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

  • Если это нормально для человека, чтобы переместить, то почему бы не использовать публичный сеттер для изменения адреса? Конечно, вы должны проверить, действительно ли адрес. Кроме того, если перемещение - это бизнес-процесс (т.е. Вы перемещаете кого-то в отель), тогда было бы хорошо иметь эту операцию в службе домена (которая будет проверять, что комната назначения пуста и готова).

  • Разрешить изменение имени в порядке. Обычно имя не является идентификатором для таких объектов, поэтому оно может меняться.

Кроме того, я представил объекты ценности для электронной почты и телефона. Я считаю, что не является ответственностью за проверку правильности адреса электронной почты. Переместите это в класс Email. То же самое с телефоном и адресом.


Много методов добавления/изменения и конструктор перегружает последствия 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. Проверки проверки имен происходят, когда имена создаются, а не когда они передаются в класс Person.

ChangeContacts метод принимает три необязательных параметра, любые из которых могут отсутствовать. Специальный тип Maybe указывает, что они являются необязательными. Специальные типы Address, Phone и MailAddress указывают, что эти параметры уже действительны и нет необходимости снова проверять их в классе Person.

Случай использования

Лицо женится и изменяет фамилию

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)

Шаблон должен вызвать метод обновления со старыми значениями + некоторые новые значения.

licensed under cc by-sa 3.0 with attribution.