【问题标题】:DDD - Rehydrate aggregate roots?DDD - 补水聚合根?
【发布时间】:2017-07-20 22:15:18
【问题描述】:

我所有的实体都是接口的实现。它们的大部分属性都是只读的。
我的存储库包含对我拥有所有接口的库项目的引用,因此从技术上讲,存储库可以保存聚合根而不知道它的实际实现(我相信这是一个+1).
这里的问题是:如果大多数属性都是只读的,我怎样才能在不破坏 OOP 原则的情况下重新水化聚合根?存储库是否应该包含对域项目的引用并了解接口的具体实现?

【问题讨论】:

    标签: oop domain-driven-design ddd-repositories


    【解决方案1】:

    存储库是否应该持有对领域项目的引用并了解接口的具体实现?

    正如埃文斯在蓝皮书中所描述的那样; Repository 是实现所扮演的角色,以防止应用程序直接改变底层数据。类似地,Aggregate Root 是一个角色——我们不让应用程序接触实际实体,而只是它的有限部分。

    存储库的实现是模型的一部分,因此它可以更多地了解所代表的具体实体;包括知道如何从它们中提取可以传递给持久性组件进行存储的状态表示。

    要选择特定的上下文,假设我们正在为 TradeBook 建模,其中一个有趣的用例是客户下订单的用例。 在 Java 中,Repository 接口的实现——应用程序知道的位,可能看起来像

    interface API.TradeBookRepository<TradeBook extends API.TradeBook> {
        TradeBook getById(...);
        void save(TradeBook);
    }
    
    interface API.TradeBook {
        void placeOrder(...);
    }
    

    所以应用程序知道它可以访问存储库,但它对实现一无所知,只知道它的承诺 将提供支持 placeOrder 的一些东西

    所以应用程序代码如下所示:

    API.TradeBookRepository<? extends API.TradeBook> repo = ....
    
    API.TradeBook book = repo.getById(...);
    book.placeOrder(...)
    repo.save(book)
    

    但是给定的存储库实现通常与本书的特定实现耦合;它们是配对的。

    class LIFO.TradeBook implements API.TradeBook {
        ...
    }
    
    class LIFO.TradeBookRepository implements API.TradeBookRepository<LIFO.TradeBook> {
        ...
    }
    

    如何在不违反 OOP 原则的情况下重新水合聚合根?

    在某种程度上,你不能。好消息是,at the boundaries, applications are not object oriented

    您放入持久存储的东西不是聚合根;这是状态的某种表示。我倾向于将其视为Memento。您真正拥有的是两个函数 - 一个将特定聚合根实现(例如:LIFO.TradeBook)转换为 Memento,另一个将 Memento 转换为聚合根。

    关键思想:与迁移数据库相比,您可能想要更频繁地更改域模型很多。所以 Memento 需要设计成稳定的——实际上,Memento 是从旧域模型发送到新域模型的消息,所以很多 lessons of message verioning 都适用。

    【讨论】:

      【解决方案2】:

      简单地说,您的应用程序中的某处必须了解具体的实现。如果您真的想保护存储库实现(而不是合同)不知道具体实体,那么该责任将不得不落在另一个协作者身上(例如存储库会将再水化委托给抽象工厂)。

      但是,为聚合拥有单独的合同是非常少见的,因为您通常只有这些业务概念的单一实现,并且通常没有您希望在单元测试中模拟它们的场景。因此,存储库合同和实施大部分时间都是根据具体聚合来定义的。

      【讨论】:

        猜你喜欢
        • 2016-03-21
        • 2012-02-19
        • 1970-01-01
        • 2010-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-26
        • 2016-03-29
        相关资源
        最近更新 更多