Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 使用实例方法和工厂方法的DDD不变强制_Oop_Design Patterns_Domain Driven Design_Factory Pattern_Aggregateroot - Fatal编程技术网

Oop 使用实例方法和工厂方法的DDD不变强制

Oop 使用实例方法和工厂方法的DDD不变强制,oop,design-patterns,domain-driven-design,factory-pattern,aggregateroot,Oop,Design Patterns,Domain Driven Design,Factory Pattern,Aggregateroot,我正在使用领域驱动的设计原则设计一个系统。 我有一个名为相册的集合 它包含一组曲目s. Album实例是使用名为create(props)的工厂方法创建的 规则1:专辑必须至少包含一首曲目 创建时必须检查此规则(在相册中创建(道具))。 此外,必须有一个名为addTrack(track:track)的方法,以便在创建实例后可以添加新的track。这意味着addTrack(track:track)也必须检查规则。 如何避免这种逻辑代码重复?好吧,如果相册在实例化时确保它至少有一个音轨,我不明白为

我正在使用领域驱动的设计原则设计一个系统。
我有一个名为
相册
的集合
它包含一组
曲目
s.
Album
实例是使用名为
create(props)
的工厂方法创建的
规则1:
专辑
必须至少包含一首
曲目

创建时必须检查此规则(在
相册中创建(道具)
)。
此外,必须有一个名为
addTrack(track:track)
的方法,以便在创建实例后可以添加新的
track
。这意味着
addTrack(track:track)
也必须检查规则。

如何避免这种逻辑代码重复?

好吧,如果
相册
在实例化时确保它至少有一个
音轨
,我不明白为什么
添加音轨
会担心违反规则?您的意思可能是
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.');
  }
}
类相册{
建造商(轨道){
这个。_tracks=[];
该资产将有一个轨道(轨道长度);
//添加曲目
}
removeTrack(trackId){
此._资产将有一个机架(-1);
//移除轨道
}
_资产将有一个机架(更改){

如果(this._tracks.length+change,我明白了。关于不让客户端代码创建曲目,您建议让客户端代码创建值对象,而不是像track这样的实体?为什么?我也可以在工厂内创建值对象吗?@plalx此外,像Album、track、User等聚合通常会更新其所有属性(几乎全部)。我应该创建一个实例方法来设置每一个吗?还是只使用一个简单的setter?@plalx原因是,如果客户端可以在
相册
的上下文之外修改
曲目
,那么不变量就无法得到保护。例如,如果不能有两个同名曲目,客户端可能会违反规则:
track1=new Track('foo');album=new album(track1);album.addTrack(new Track('track2'));track1.changeName('track2');//违反规则
好吧,DDD战术模式可能会妨碍CRUD。如果您只做CRUD,那么就不希望有一个非常有趣且面向行为的模型。如果业务流程是“更新”/“更改跟踪信息”,然后您可以执行
album.changeTrackInfo(trackId,newTrackInfo)
。请注意,如果您不关心特定曲目的生命周期,那么从模型的角度来看,
曲目
也可能是一个值对象。明白了。我认为
曲目
是一个实体,因为我将存储用户收听的每个曲目的数据。非常感谢@plalx。我想我现在就知道了。