Domain driven design 聚合和根聚合创建的DDD有效建模
我们正在启动一个新项目,我们渴望应用DDD原则。该项目使用dotnetcore,efcore为sqlserver提供持久性 域的初始视图 我将使用一个任务跟踪器的示例来说明我们的问题和挑战,因为这将遵循类似的结构 一开始,我们理解如下:-Domain driven design 聚合和根聚合创建的DDD有效建模,domain-driven-design,aggregate,Domain Driven Design,Aggregate,我们正在启动一个新项目,我们渴望应用DDD原则。该项目使用dotnetcore,efcore为sqlserver提供持久性 域的初始视图 我将使用一个任务跟踪器的示例来说明我们的问题和挑战,因为这将遵循类似的结构 一开始,我们理解如下:- 我们有一个项目 用户可以关联到项目 项目具有工作流 工作流具有任务 用户可以针对任务发布评论 用户可以更改任务的状态(正在进行、完成等) 项目,以及相关的工作组和任务最初是从模板创建的 最初的设计是一个大型集群聚合,项目是包含项目用户和工作流集合的根聚合,
- 我们有一个项目
- 用户可以关联到项目
- 项目具有工作流
- 工作流具有任务
- 用户可以针对任务发布评论
- 用户可以更改任务的状态(正在进行、完成等)
- 项目,以及相关的工作组和任务最初是从模板创建的
- 一个项目聚合,它只包含分配给该项目的用户列表
- 包含项目外键的工作流聚合
public class Project()
{
string _name { get; private set;}
public Project(Name)
{
_name = Name;
}
public Workstream CreateWorkstream(string name)
{
return new Workstream(name, Id);
}
....+ Methods for managing user assignment to the project
}
以类似的方式,Workstream有一个创建任务的方法
public class Workstream()
{
string _name { get; private set;}
public int ProjectId { get; private set; }
public Workstream(Name, Id)
{
_name = Name;
_projectId = Id;
}
public Task CreateTask(string name)
{
return new Task(name, Id);
}
private readonly List<Task> _activities = new List<Task>();
public IEnumerable<Task> Activities => _activities.AsReadOnly();
}
公共类工作流()
{
字符串_name{get;private set;}
public int ProjectId{get;private set;}
公共工作流(名称、Id)
{
_名称=名称;
_projectd=Id;
}
公共任务CreateTask(字符串名称)
{
返回新任务(名称、Id);
}
私有只读列表_活动=新列表();
public IEnumerable Activities=>_Activities.AsReadOnly();
}
- 添加Activities属性纯粹是为了在使用实体构建读取模型时支持导航
- 人们认为,在逻辑上创建项目应该是创建项目,向项目中添加一个或多个工作流,向工作流中添加任务,然后让EF处理持久化该对象结构的问题
- 令人不安的是,必须首先创建项目,并且开发人员需要确保项目被持久化,以便获得一个Id,以便在调用创建模板的方法时准备就绪,该方法依赖于外键的Id。将这方面的责任推给域服务CreateProjectFromTemplate()中的一个方法来协调各个存储库中单独对象的创建和持久化,可以吗
- 创建新工作流的方法是否在正确的位置
- 实体用于形成用于创建读取模型的查询(导航属性支持)。可能需要考虑的是,对象结构正受到以只读方式显示数据的方式的影响
我们现在正处在一个循环的阶段,我们真的需要一些建议来给我们一些方向。这里有一个不同的视角,可能会推动你走出僵局 我觉得你在做数据建模,而不是真正的领域建模。您关心的是将使用ORM(EF)直接持久化的关系模型,而不是实际问题域。这就是为什么您担心项目将加载太多的内容,或者哪些对象将保存哪些内容的外键 另一种方法是暂时忘记坚持,专注于事情可能需要什么样的责任。关于责任,我指的不是像保存/加载/搜索这样的技术性东西,而是领域定义的东西。如创建任务、完成任务、添加注释、,
{
taskId: 67890,
projectId: 12345
}