领域驱动设计 – 存储库模式:如何延迟加载?或者,我应该拆分这个聚合?

前端之家收集整理的这篇文章主要介绍了领域驱动设计 – 存储库模式:如何延迟加载?或者,我应该拆分这个聚合?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个领域模型,有编辑器和项目的概念。

编辑器拥有多个项目,并且一个项目不仅具有编辑者所有者,还包括多个编辑者成员。因此,编辑器还具有多个“已合并”项目。

我采取一个DDD方法来建模和使用Repository模式的持久性。然而,我没有足够好的模式,以确定我应该怎么做。

我的工作是假定编辑器和项目可能在同一个聚合,根是编辑器。我可以得到一个编辑器,然后枚举其项目,并可以从那里枚举项目的成员编辑。

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

或者,如果我拆分聚合并有一个Editor存储库和一个Project存储库,我应该如何处理两个事务,例如当一个新的项目添加到编辑器?例如:

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

我是否错误地解释了Repository模式的意图?

Am I misinterpreting the intent of the Repository pattern?

我要说“是”,但是知道我和我工作过的每个人都因为同样的原因问了同样的事情……“你不是在四维上思考,马蒂。

让我们简化一下,坚持使用构造函数,而不是首先创建方法

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);

但是放在哪里呢?不在项目或编辑器中,你是对的,或者他们将必须访问存储库,这是不好的。上面的代码段是松散耦合的,但是不能自己重用。您刚刚达到了Repository Pattern的限制。

接下来是一个适配器层为您的应用程序,与共享资源库(StaticServiceWrapper)和一些EditorAdapter对象(或聚合或任何你称之为它们)或现在你可以混合扩展方法,可以与任何和所有必要的存储库流畅。我在生产系统中没有这么做,但是给你一个简明的例子:

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,添加,更新,删除对象存储库完成后,你必须离开关联单独,向上移动对象/层层次到有趣的部分,如适配器和缓存和业务逻辑(“哦,我的!“)。

猜你在找的设计模式相关文章