在应用程序中,我们已将其建模Company
为实体和Address
值对象:
public class Company : Entity {
public Address PrimaryAddress { get; set; }
public Address SecondaryAddress { get; set; }
}
public class Address : ValueObject {
public string ZipCode { get; private set; } // etc.
public Address(string zipCode) {
ZipCode = zipCode;
}
}
在这里,Address
没有身份并且是不可变的。为了更新PrimaryAddress
公司,我将其替换为新Address
对象。
但是,在进一步发现该域后,我们发现一家公司可能拥有可变数量的地址。将它们表示为单独的属性不再可行。所以我们重构了Company
:
public class Company : Entity {
public Address[] AddressBook { get; set; }
}
我们现在有一个问题是如何更新公司的Address
. 我们现在关心地址的身份,但仅在 Company 的上下文中。
重构之后,我们最终得到:
public class Company : Entity {
public Address[] AddressBook { get; set; }
public void UpdateAddress(Address newAddress) {
var oldAddress = AddressBook.FirstOrDefault(a => a.Id == newAddress.Id);
if (oldAddress != null)
oldAddress = newAddress;
}
}
public class Address : ValueObject {
public Guid Id { get; private set; }
public string ZipCode { get; private set; } // etc.
public Address(Guid id, string zipCode) {
ZipCode = zipCode;
Id = id;
}
}
// usage
var company = repo.Load<Company>(companyId);
var address = new Address(model.Id, "12345"); // uses id of address we are replacing
company.UpdateAddress(address);
repo.Save(company);
为了更新地址,我们使用它来定位它,并将其Id
替换为具有相同ID 的新地址对象。
- 因此 Address 仍然是一个值对象吗?
- 我对更新的地址使用相同的ID 是否正确,或者根据定义(作为值对象)我们应该替换Id。
- 如果地址仅在公司实体的上下文中具有身份,我们是否应该在我们的模型中明确这一点,也许生成一个仅在实体内部唯一的 ID(可能使用实体的 ID 作为计算的一部分)?