问题描述
创建实例
我对DDD不熟悉,想知道创建实体的 Factory 是否负责创建 Value Objects 。这是到目前为止我所拥有的一个小例子:
class User extends Entity {
public name: UserName;
constructor (name: UserName) {
this.name = name;
}
}
class UserName extends ValueObject {
public userName: string;
}
class UserFactory {
public create(string name) {
return new User(
new UserName(name)
);
}
}
我认为,创建用户(UserEntity)的组件只需将字符串传递给工厂,仅此而已。但另一方面,此代码未遵循单一责任原则。也许最好直接传递 UserName 值对象?
class UserFactory {
public create(UserName userName) {
return new User(
userName
);
}
}
验证
我仍然不清楚的另一个概念是验证。谈论创建对象( UserEntity)时的验证。 UserFactory 是否对此负责?例如:
class UserFactory {
public create(UserName userName,UserLastName userLastName) {
if (userName == userLastName)
// throw validation exception
return new User(
userName,userLastName
);
}
}
我将 lastName 作为 ValueObject 添加到 UserEntity 的图像。我知道比较这两个名称只是一个例子而已。 因此,这种方法是否正确-从 UserEntity 中删除责任或以下代码段更好:
class User extends Entity {
public name: UserName;
public lastName: UserLastName;
constructor (name: UserName,lastName: UserLastName) {
if (name == lastName)
// throw validation exception
this.name = name;
this.lastName = lastName;
}
}
对我来说,最有趣的是 Entity 的构造函数发生变化(向构造函数添加更多必需的参数)。我正在搜索将导致尽可能少的更改的方法-仅使用 Entity 构造函数的 Factory模式?与简单的方法-构造函数(如果有)相比,使用 Factory 的最大优势是什么。
解决方法
我认为您可能正在使事情复杂化。工厂模式实际上并不是DDD的一部分,但它是在构建对象很复杂或您要隐藏实体需要工作的某些属性时使用的设计模式(例如,在UI中,元素可能需要一些访问权限)到执行渲染的类)。如果您去duckduckgo并搜索design factory pattern
您显示的示例并不需要工厂。如果工厂所做的一切只是将参数传递给构造函数,那么它就不会添加任何内容。
关于验证,其思想是,如果对象不可用,则构造函数永远不会成功返回,因此在您的示例中,如果参数不能为null,则null验证应该在对象的构造函数中。
关于价值对象,同样,为什么需要工厂?它带来什么好处?老实说,我无法想到拥有Factory类是有意义的。有时,为了使代码更简洁一点,可以使用工厂方法。例如,在Java中,只能通过调用静态生成器方法Optional.of()
来构造Optional类(顺便说一句,它做了一些仅适用于该方法的额外验证)。
TL; DR:如果可以带来好处,请使用Factory类,否则直接实例化该类。