将CQRS与DDD结合起来?

时间:2014-08-29 22:50:37

标签: design-patterns architecture domain-driven-design cqrs

对于我的大多数应用程序,我使用直接的DDD方法,这意味着分离洋葱架构的层,将域与基础架构分离等。两个经常重复的构建块,存储库和事件总线,看起来像这样(简化)。

public interface IRepository<TEntity, TKey>
    where TEntity : EntityBase<TKey>
{

    void Add(TEntity entity);

}

public interface IEventBus {

    void Publish<TEvent>(TEvent @event)
        where TEvent : IEvent;

}

最近,我开始研究CQRS,并且我认识到许多类似的模式,例如存储库,事件和放大器。指挥巴士。但是,例如CQRS中的存储库不负责存储/检索实体,而是负责管理聚合和构建事件流。

现在我想知道:他们俩一起工作吗?或者他们是完全不同的方法,只是分享一些常见的东西?

1 个答案:

答案 0 :(得分:18)

是的,它们是完全不同的方法:CQRS does not mean event sourcing,而是意味着将写入与读取分开。您可以在有和没有事件来源的情况下进行CQRS,这些概念彼此正交。

话虽如此,很明显,使用CQRS式架构,您的存储库仍然负责存储和检索实体:存储库是域语言的一部分,并且此语言不受CQRS等架构选择的影响。非CQRS。这是CQRS应用程序的典型存储库接口,与非CQRS应用程序的存储库接口相同;此外,如果您使用的是事件来源,它仍然是相同的。

public interface IRepository<TEntity, TKey>
    where TEntity : EntityBase<TKey>
{

    void Add(TEntity entity);
    void Save(TEntity entity);
    TEntity retrieveByKey(TKey key);

}

现在,如果您使用事件源 ,那么您的存储库实现(即基础架构)将查询关系数据库并从该特定键的行中找到的数据中组装实体。如果 使用事件源,则您的存储库将负责查询事件存储,并将事件流投影到要返回的实体的当前状态。所有这些都是实现的一部分,而不是存储库接口的兴趣。