gpt4 book ai didi

domain-driven-design - 存储库模式 : how to Lazy Load? 或者,我应该拆分此聚合吗?

转载 作者:行者123 更新时间:2023-12-03 07:20:29 25 4
gpt4 key购买 nike

我有一个域模型,其中包含编辑器和项目的概念。

一个编辑者拥有多个项目,一个项目不仅有一个编辑者所有者,还拥有多个编辑者成员。因此,一个编辑器也有多个“加入”的项目。

我采用 DDD 方法对此进行建模,并使用存储库模式进行持久化。但是,我还没有充分理解该模式,无法确定应该如何执行此操作。

我正在假设编辑器和项目可能位于同一聚合中,根为编辑器。因此,我可以获得一个编辑器,然后枚举其项目,并可以从那里枚举项目的成员编辑器。

但是,如果我只允许从我的存储库中检索编辑器,这是否意味着当我获得拥有它们的编辑器时,我必须从存储库中加载所有项目?如果我想延迟加载成员编辑器,项目还需要对存储库的引用?

或者,如果我拆分聚合并拥有编辑器存储库和项目存储库,我应该如何处理两者之间的事务,例如将新项目添加到编辑器时?例如:

Editor e = new Editor("Editor Name");
editorRepository.Add(e);

Project p = e.CreateProject("Project Name");
projectRepository.Add(p); // These two lines
editorRepository.Save(e); // should be atomic

我是否误解了存储库模式的意图?

最佳答案

Am I misinterpreting the intent of the Repository pattern?

我会说“是的”,但要知道我和我共事过的每个人都出于同样的原因问过同样的事情......“你不是在第四维度思考,马蒂”。

让我们稍微简化一下,首先使用构造函数而不是 Create 方法:

Editor e = new Editor("Editor Name");
e = editorRepository.Add(e);

Project p = new Project("Project Name", e);
p = projectRepository.Add(p);

在下面,您的项目存储库始终在创建项目数据时将有效所有者 (p.EditorId) 存储到项目数据中,无论您如何重新填充编辑器的项目,它都会在那里。这就是为什么将所有必需的属性放入构造函数中是一个好习惯。如果您不想传递整个对象,只需 e.Id 即可。

And if I want to lazy load the member Editors, the Project needs a reference to the repository as well?

现在,至于如何根据需要重新填充编辑器的项目,您有几种选择,具体取决于您的目的。 Straight Repository 说你想要:

IEnumerable<Project> list = projectRepository.GetAllProjects()
.Where(x => x.editorId == e.Id);

但是该把它放在哪里呢?不在项目或编辑器内部,你是对的,否则他们将必须访问存储库,这不好。上面的代码片段是松散耦合的,但不能单独重用。您刚刚达到了存储库模式的极限。

接下来是您的应用程序的适配器层,具有共享的存储库源(StaticServiceWrapper)和某种 EditorAdapter 对象(或 Aggregate 或任何您所说的名称),或者现在您可以混合扩展方法,可以流畅地与任何和所有必要的存储库对话。我还没有在生产系统中完全按照这种方式完成,但向您展示一个简洁的示例:

public static class Aggregators
{
// one to one, easy
public static Editor GetOwner(this Project p)
{
return StaticServiceWrapper.editorRep.GetEditorById(p.editorId);
}

// one to many, medium
public static IEnumerable<Project> GetProjects(this Editor e)
{
return StaticServiceWrapper.projectRep.GetAllProjects()
.Where(x => x.editorId == e.Id);
}

// many to many, harder
public static IEnumerable<Editor> GetMembers(this Project p)
{
var list = StaticServiceWrapper.projectMemberMap.GetAllMemberMaps()
.Where(x => x.projectId == p.projectId);

foreach ( var item in list )
yield return StaticServiceWrapper.editorRep.GetEditorById(item.editorId);
}
}

基本上,一旦您的 GetAll、GetById、添加、更新、删除对象存储库完成,您就必须保留关联并继续沿着对象/层层次结构向上移动到适配器、缓存和业务逻辑等有趣的部分(“哦,天哪!”)。

关于domain-driven-design - 存储库模式 : how to Lazy Load? 或者,我应该拆分此聚合吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/458146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com