我尝试使用DDD模式并作为持久存储我考虑使用像LiteDB,RavenDB或DocumentDB这样的NoSQL数据库。
与关系数据库相比,我的一个优点是,我的域模型(整个聚合)可以序列化为JSON文档,并存储在数据库中,避免域模型到数据模型映射。
但是为了在屏幕上显示数据而读取数据又如何呢?我的UI是基于视图模型显示视图,但是如何构建它们?我是否通过查询文档数据库。我的域模型,然后将其映射到视图模型?
我问这个,因为它经常被提到"不要使用您的域模型进行查询(阅读模型)"。
答案 0 :(得分:1)
是的,那很好。与关系数据库相比,我的一个优点是,我的域模型(整个聚合)可以序列化为JSON文档,并存储在数据库中,避免域模型到数据模型映射。
但是为了在屏幕上显示数据而读取数据又如何呢?我的UI是基于视图模型显示视图,但是如何构建它们?我是否通过查询文档数据库。我的域模型,然后将其映射到视图模型?
是。有趣的问题是何时。
您可以与请求同步执行此操作。
您可以与请求同步执行此操作,但会缓存结果,以便后续查询同一视图的速度更快。
您可以异步执行此操作 - 使用后台进程将视图加载到缓存中,以便快速查看所有查询。
基本思想是每次编写对文档的更改时,都会向异步进程发出更改已发生的信号,然后该进程会加载更新缓存视图所需的数据。
"缓存"例如,可能是一个文档存储,它包含您最近组成的视图模型。
缓存视图还可能包含元数据,允许在请求时确定是否需要重建视图。在考虑缓存元数据时,RFC 7234可能是一个很好的起点。
正如Pawel所说,将写模型和阅读模型分开是cqrs的主题。很多文献都很安静。我建议从Martin Fowler's overview开始。
答案 1 :(得分:1)
了解您的域模型包含行为和状态非常重要。你唯一需要坚持的就是国家。
当你意识到这一点时,你也会发现聚合状态对于运行查询并不可怕。但是你绝对不应该使用你的存储库来组成读/视图模型 - 简单的查询就足够了。将域对象状态分离为简单的DTO(文档)变得很方便,您将存储在数据库中,并将它们作为域对象中的属性保存。这与书中所示的略有不同,但在实践中它运作良好。如果你的封装足够好并且不会编写序列化和持久性测试,你至少会担心。 This article在状态对象部分支持的域对象下提及它。