注意:我正在使用PHP,但我认为这个问题将被认为是语言不可知论。我也在实现"生活DDD",但我不认为这限制了问题。
我有一个类(实体),它有很多可以设置的属性(我也有很多关于实体的行为,所以它不是一个贫血的领域模型)。
例如,我有许多字符串属性,看起来像这样:
public function setFirstName($firstName)
{
// Removes all non-printable characters and extra spaces.
// Also converts all "look-a-like" quotes to the standard quote character.
$firstName = Helper::cleanName($firstName);
if(empty($firstName)){
throw new Exception("first name is required");
}
$this->firstName = $firstName;
}
坚持DRY,我看到了创建"干净名称"值对象的好处。但这会把几乎所有的字符串属性都变成这些值对象。我还有其他属性,它们是日期,我将把它们转换为Carbon日期值对象。最后,似乎几乎每个属性(将被持久化)都变成了一个值对象。我担心是否过度使用这种方法,或者是否会出现任何与内存相关的问题(特别是在这些实体的较大集合中)。
如何判断一个类是否过度使用值对象?Ie。是否有一个最低标准的逻辑量被封装为一个有价值的对象?通过将几乎每个属性(将被持久化)都作为值对象,我是否会占用内存?有没有人遇到过带有30多个值对象的类的问题?
根据Mathias Verraes出色的演讲Unbreakable Domain Models,他提到值对象是编程的"心脏和灵魂"。所以我认为最终的答案是在使用值对象时不要害羞。
然而,在考虑了我在问题中提到的验证类型(从这些名称中清除字符等)之后,我决定将其转移到表单输入处理程序类。在进入域之前,在"应用程序级别"做一些清理工作感觉会好一些。当然,如果我开始进行任何需要领域逻辑的验证,那么我应该总是在领域级别上进行验证。我认为碳年代应该保留。我也有一个名为"urlSafeName"(或slug)的属性,我正在考虑制作一个值对象(接受字符串并将其转换为更"漂亮的url"形式)。
我仍然有点担心VO保存数组,可以代替数据库中非常小的表。例如,来自一系列职位(总裁、CTO、首席开发人员等)的职位名称的VO。我必须确保数组将保持在一个可管理的大小,这个大小当然是主观的。如果我有一个带有cityId、stateId和countryId的地址VO,那么我可能只想将它们存储为id,而不是将这些城市、州和国家的所有名称存储在VO中(但应该存储在数据库中的查找表中)。