将值对象传递给实体方法

本文关键字:实体 方法 对象 | 更新日期: 2023-09-27 18:25:51

将值对象传递给实体方法(根据DDD)的良好实践?例如,我在我的实体Customer中有一个方法:

SetAddress(Address invoiceAddress); 

它有效吗?或者我应该将地址参数作为传递

SetAddress(string street, string town, string zip, string country);

并让客户处理地址对象的创建,如果需要,则抛出异常。

地址是不可变的对象。

将值对象传递给实体方法

您肯定应该传递一个Address对象。就DDD而言,它是有效的,而且它还具有良好的可扩展性(即,您可以在不更改SetAddress方法签名的情况下向Address对象添加更多字段)。

此外,Address对象应该包含地址信息的验证逻辑,Customer.SetAddress(...)方法可以在设置地址之前执行该逻辑:

public class Customer
{
    public SetAddress(Address invoiceAddress)
    {
        // ToDo: Execute validation logic encapsulated in 'Address' object
        // ToDo: Execute additional validation logic here
    }
}

从面向对象的角度来看,SetAddress()的三个参数表示Address,因此应该封装到Address类的一个实例中。虽然我不知道为什么你有一个方法来执行SetAddress,但你不能用setter代替吗?

如果SetAddress()是公开的,那么方法的调用者就不必担心3个不连贯的字符串参数。更重要的是,参数的顺序不能通过查看函数名来确定(SetAddress()不提供任何信息,无论参数的顺序是:street、town、zip、country还是street、town、country、zip)。调用方很容易混淆参数的顺序。

为了避免这种情况,SetAddress()最好接受其名称中明确指示的类型的参数,即Address的实例。

您可以将工厂方法作为Address 的一部分

public class Address
{
    public static Create(string street, string zip)
    {
        return new Address { Street = street, Zip = zip };
    }
}

其思想是Create的参数显示创建Address对象的强制属性。

var address = Address.Create("street", "zip");
customer.SetAddress(address);