Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 大量的添加/更改方法和构造函数重载是DDD的结果吗?_C#_Domain Driven Design_Domain Model - Fatal编程技术网

C# 大量的添加/更改方法和构造函数重载是DDD的结果吗?

C# 大量的添加/更改方法和构造函数重载是DDD的结果吗?,c#,domain-driven-design,domain-model,C#,Domain Driven Design,Domain Model,我有一门课: 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 Add

我有一门课:

    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个额外的重载以提供该选项是否正确
  • 我应该允许在可选属性上使用公共setter并在那里进行验证吗
  • 如果此人结婚并更改了姓氏,我是否需要其他方法来更改姓氏,还是应该将此setter也公开,并且只在构造函数中要求它们

  • AddOrChange
    相当于带有公共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;
        }
    }
    
  • 若用户在创建人员时希望提供所需数据之外的其他内容,则可以使用类初始值设定项。您还可以向构造函数添加一些可选参数

    var-bob=新人(“bob”,“叔叔”){Address=someAddress}

  • 若人们可以重新安置,那个么为什么不使用公共设置器来更改地址呢?当然,您应该检查地址是否有效。另外,如果重新定位是一个业务流程(即,您正在酒店重新定位某人),那么在域服务上执行此操作(该操作将验证目标房间是否已空且准备就绪)将是一件好事

  • 允许更改名称是可以的。通常,名称不是此类实体的标识,因此它可能会更改

  • 此外,我还为电子邮件和电话引入了价值对象。我认为这不是个人的责任,以验证是否电子邮件地址有效。移动到电子邮件类。电话和地址也一样

  • 没有
  • 公开
  • 假设在
    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";
    

    大量的添加/更改方法和构造函数重载是DDD的结果吗

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

    代码

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

    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
    方法接受三个可选参数,其中任何一个都可以不存在。Special
    Maybe
    类型表示它们是可选的。特殊的
    地址
    电话
    邮件地址
    类型表示这些参数已经有效,无需在
    人员
    类中再次验证它们

    用例

    此人结婚并更改姓氏

    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)
    
    丢失电话号码的人

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

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

    完全不同意。。。属性的语义与我的2美分不同:Setter说,某些依赖项或数据可以更改。如果您想为更改流程命名,则由您决定。例如,使用方法
    重新定位
    而不是
    地址的setter
    。但是除了我们已经知道的以外,
    AddOrChange
    没有带来任何新的东西。这只是糟糕的方法名称,我仍然认为应该有用于此的命令方法,只有其他名称。。当前域语言中的动词名称。。否则就不是很DDD了all@RogerAlsing你真的认为属性不应该用在DDD应用程序中吗?你的属性语法有点不正确;您需要创建一个支持字段,并从属性中手动设置/返回它。@Servy:完全正确。这就是我复制/粘贴和快速键入的结果。固定。电子邮件和电话应该是像地址一样的有价值的对象。他们将自己进行验证。此人不应该关心验证它们,有效的电子邮件或电话是其他对象可以使用的对象,它们应该始终处于有效状态。@MikeSW谢谢。您可能是对的,这将是一个优雅的解决方案,为类似的字段使用更多的值类型,以便可以反复使用。