DDD - 使用实例方法和工厂方法的不变执行
DDD - Invariant enforcement using instance methods and a factory method
我正在使用领域驱动设计原则设计一个系统。
我有一个名为 Album
.
的聚合
它包含 Track
的集合。
Album
个实例是使用名为 create(props)
.
的工厂方法创建的
规则 1:一个 Album
必须至少包含一个 Track
.
必须在创建时检查此规则(在 Album.create(props)
中)。
此外,必须有一个名为 addTrack(track: Track)
的方法,以便在创建实例后可以添加新的 Track
。这意味着 addTrack(track: Track)
也必须检查规则。
如何避免这种逻辑代码重复?
好吧,如果 Album
确保它在实例化时至少有一个 Track
我不明白为什么 addTrack
会担心规则可能会被违反?您的意思是 removeTrack
吗?
在这种情况下,您可以选择如下简单的方法:
class Album {
constructor(tracks) {
this._tracks = [];
this._assertWillHaveOneTrack(tracks.length);
//add tracks
}
removeTrack(trackId) {
this._assertWillHaveOneTrack(-1);
//remove track
}
_assertWillHaveOneTrack(change) {
if (this._tracks.length + change <= 0) throw new Error('Album must have a minimum of one track.');
}
}
请注意,您也可以先改变状态,然后检查规则,乍一看这会使事情变得更简单,但这通常是一种不好的做法,因为如果处理了异常,模型可能会处于无效状态,除非模型还原更改,但这会变得更加复杂。
另请注意,如果 Track
是一个实体,最好不要让客户端代码创建 Track
来保留封装,而是传递一个 TrackInfo
值对象或类似的东西。
我正在使用领域驱动设计原则设计一个系统。
我有一个名为 Album
.
的聚合
它包含 Track
的集合。
Album
个实例是使用名为 create(props)
.
的工厂方法创建的
规则 1:一个 Album
必须至少包含一个 Track
.
必须在创建时检查此规则(在 Album.create(props)
中)。
此外,必须有一个名为 addTrack(track: Track)
的方法,以便在创建实例后可以添加新的 Track
。这意味着 addTrack(track: Track)
也必须检查规则。
如何避免这种逻辑代码重复?
好吧,如果 Album
确保它在实例化时至少有一个 Track
我不明白为什么 addTrack
会担心规则可能会被违反?您的意思是 removeTrack
吗?
在这种情况下,您可以选择如下简单的方法:
class Album {
constructor(tracks) {
this._tracks = [];
this._assertWillHaveOneTrack(tracks.length);
//add tracks
}
removeTrack(trackId) {
this._assertWillHaveOneTrack(-1);
//remove track
}
_assertWillHaveOneTrack(change) {
if (this._tracks.length + change <= 0) throw new Error('Album must have a minimum of one track.');
}
}
请注意,您也可以先改变状态,然后检查规则,乍一看这会使事情变得更简单,但这通常是一种不好的做法,因为如果处理了异常,模型可能会处于无效状态,除非模型还原更改,但这会变得更加复杂。
另请注意,如果 Track
是一个实体,最好不要让客户端代码创建 Track
来保留封装,而是传递一个 TrackInfo
值对象或类似的东西。