28 Comments

  1. 简晴

    好文章,最近也在实施DDD,想问一下作者里面提到的 菜品设计上应对 不同 种类的菜时说应该抽象出分类这个模型,而不是对菜的继承,这个具体怎么实现呢,或者是更具体点:京酱肉丝,油焖大虾 ,这两种菜,在具体的实现中,不用继承,该怎么去实现这两个业务对象,我能想到就是有菜这样的父类,然后京酱肉丝和油焖大虾都是子类,(也想到接口实现,但是菜本身会有些共同属性和方法,所以还是抽象类比较合适), 当然可能脱离文中所举的热菜冷菜这样的例子,(热菜和冷菜可以抽象一个temperature , 这个我能懂),在这种具体的菜品上,共性和个性的业务逻辑如何在代码里表示会更好呢?

    • 林宁 林宁

      ”共性和个性的业务逻辑如何在代码里表示会更好呢?“ 这个问题恐怕太大了,如果有一个答案程序员就该失业了。我理解还是抽象层次,抽象层次高共性就多,抽象层次低就全是个性化代码。但是关键在于抽象层次高,成本也高(这也是 Java 为什么天天被吐槽复杂的原因,但是换个语言过不了几天又会从 java 中借去各种概念),如何适度抽象真的是一个手艺活。

      对我而言,为什么用组合而不是继承,更多是考虑基于范式理论的数据存储问题。继承不是坏事,但是大部分业务代码确实没必要用继承,关键的问题是”继承“这个关系怎么存呢?

      • 简晴

        其实 大部分 在考虑 DDD的时候,都抛弃了数据库存储这个问题,我们是希望 可以非常干净的去思考模型设计,而不被数据存储而影响,一个理想的状态就是假设有个巨大的内存供你使用,你可以随意存取数据,是在这样的基础之上去考虑DDD 的,所以就不会存在 继承 这样的关系 怎么在数据库中体现这样的问题了。

        当然,其实际上在目前的阶段,我们依然底层用的是关系数据库,依然要考虑数据库的设计,否则数据存取上会有很大的复杂度,所以 楼主的思考也有一定的道理,但这一定是需要慢慢去弱化的东西。

        其实我是赞成 多用组合少用继承的,软件开发的原则中合成复用原则就已经说明了,但这个好处还没有完全感知到,只是模糊的认为在业务和模型上多用组合肯定是有好处的,我想我要结合业务和代码再多思考一下,最终是可以体会到的。

        • 汝峰

          选择继承还是组成,一方面组合是运行时动态的,相对于继承来说更加灵活。另一方面,继承关系会给重构带来很多阻碍,调整父类的结构可能会导致子类也跟着调整。

    • zzz607

      现实中,经常可以在饭店的菜单上看见首页上写着大大的 招牌菜,那么,这个招牌菜真的是菜本身的一个属性吗?应该不是的吧。所以,针对这个需求,应该抽象出 菜品组 这个实体,和菜品是多对多的关系。这样,是不是解决了你的继承疑问

  2. 非常好的文章,看评论也是受益匪浅啊。

    我发现我自己对“组合优于继承”也是带着一种确实是赞同、也一直这么做,但是却对其好处感受比较模糊的状态。可能我代码经验还不够多吧… 倒是比较希望有一些这方面的独到“洞见”(wink

  3. Jack Liang

    你好,我先请教一下,用户的权限应该在哪一层进行控制。比如用户只能修改自己的订单,而不能修改别人的订单

    • 林宁 林宁

      个人理解,应用层做方法级别的用例权限,用注解或者URL匹配很简单就做了。数据权限在领域层,涉及业务逻辑。

      下篇文章会讨论每层的职责,这个问题细节挺多的。

  4. 微笑刺客

    对于最后那个用户创建那个demo比较感兴趣,可惜没有代码了,那个用户创建那块涉及到多个聚合的操作了吧?

  5. 笑小刀

    很有收获的一篇文章,拜谢。
    因为是带着疑问来的,所以提几点疑问:
    1. 领域服务是必要的妥协。也就是在聚合能独立完成的,应聚合完成;无法独立完成时,建议采用领域服务吗?
    2. 一个限界上下文内,可能存在多个聚合。如果多个聚合参与协作,可以直接这样操作吗?如:使用领域服务,在领域服务内,设计到其他聚合的业务时:OtherDomainRepo.find() -> otherDomain.execute() -> OtherDomainRepo.save()

    • 林宁 林宁

      在我早期的认识里面认为因为由聚合自己完成(符合 Eric 那本书),但是在后期不这样认为了。
      在认识论中任何事务的完成都需要具备:主体、客体以及主客关系。
      这里的 domain service 应该是主体,所以需要一直存在。

      • 坐看落花

        同意, doMainService 可以提供中等粒度的接口, 我之前的想法是domainService是补充的做法, 这个在单体应用中是可行的, 但是在微服务中domainService是必不可少的, 基础服务直接暴露模型会让应用层调度有难度, 毕竟领域服务 相对于 应用服务 也算是外部服务了, 它不需要了解领域服务的细节

        • 林宁 林宁

          架构就是把合适的组件放到合适地方的艺术,每个组件、类都有它的意义,如果没有就省略掉。按照奥卡姆剃刀原则,如无必要,勿增实体。

  6. 南辕北辙

    有个问题请教下,基础设施的入参和出参模型不一定是po(持久),入参我定义为特殊qo(查询),出参大概率大家定义为dto,但是dto太宽泛,有没有什么更好的定义?

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据