手把手教你落地 DDD
钟敬
Thoughtworks 首席咨询师、数字化转型与运营团队 DDD 负责人
19697 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
AIGC特别策划 (2讲)
结束语&结课测试 (2讲)
手把手教你落地 DDD
15
15
1.0x
00:00/00:00
登录|注册

24|泛化建模(下):怎样权衡是否采用泛化?

你好,我是钟敬。
前两节课,我们重点结合报工时的需求来讨论了关于泛化的问题。在第 22 课,我们为工时项建模的时候使用了泛化;而第 23 课,在为客户项目和内部项目建模时,尽管可以泛化,最终却没有采用泛化。
你可能会有个困惑:前两节课的例子里,是否采用泛化,似乎完全是凭经验和直觉,有没有更多规律可循呢?
事实上,要学会一项技术,不仅要知道什么时候用它,更要知道什么时候不用。泛化虽然很有用,但也是一种容易被过度使用的技术。
是否要采用泛化,有时并没有唯一正确的答案,而是个权衡问题。站在业务的角度,泛化可以让我们通过抽象思维而得到更深刻的领域知识,并且运用得当的话可以使模型更简洁。但另一方面,也正是由于有些抽象,所以有时反而让模型变得费解。而站在开发人员的视角,还需要考虑技术上是否容易实现,是否容易保证代码和模型一致性的问题。
既然是“权衡”,那么必然有一些“艺术”的成分在里面。不过,我们今天还是尽量找出一些规律性的东西,以便你能尽快形成“感觉”。先提示一下,后面有不少示意图,你可以边看文稿边听我说。

识别泛化的两个方向

首先,我们在建模的时候识别泛化的过程,其实有两个不同的方向。
一个方向是先识别出了子类,然后从子类中归纳出共性,形成父类。比如在第 22 课,我们先识别出项目子项目,然后发现这两者都能报工时,也就是说具有能够报工时这个共性,于是识别出了工时项这个表示共性的父类。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入讨论了在实际应用中权衡是否采用泛化建模的重要性,从识别泛化的两个方向、表示分类的两种方式以及分类的“共性”和“个性”等方面展开讨论。文章通过具体案例和逻辑学术语的引入,为读者提供了一种系统的思考方式,帮助他们更好地理解和应用泛化建模技术。文章强调了在实际建模过程中需要综合考虑业务需求、技术实现等因素,权衡是否采用泛化,并提供了三条经验指导原则,帮助读者在实践中进行决策。通过对具体案例的分析,文章展示了在不同情境下如何权衡是否采用泛化建模,以及如何从业务和技术视角综合考虑,最终做出决策。文章内容深入浅出,逻辑清晰,对于需要深入了解泛化建模技术的读者具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手教你落地 DDD》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(7)

  • 最新
  • 精选
  • 南山
    钟老师,请教个问题:像这种采用了泛化的,如何识别聚合根,比如工时管理的聚合根还是工时管理吗?项目管理的还是项目,是这样的吗?

    作者回复: 这是个很有意思的问题,就目前的例子而言,是的。总之抓住一个思路,聚合是对象和对象之间的关系,而泛化是类之间的关系。细品一下。

    2023-02-06归属地:江苏
    7
  • 子衿
    这章其实感觉读起来有点绕,我能不能这样理解一下,就是说泛化是领域模型图中的一个标识而已,要不要使用这个标识,其实只取决一一点,就是是否使用特性值的方式进行实现,如果使用特性值方式进行实现,那么因为没有父子类的概念,就会导致模型和代码不一致,因此就不应该用泛化,而文章其实整体讨论的不是应不应该使用泛化,而是讨论用具体哪种实现方式来实现分类 1. 有不同种类的特性或者不同的操作:使用继承 2. 子类在属性和操作实现方面没有共性,但有相同的操作接口:使用接口实现 3. 仅特性值不同:使用新增属性值的方式

    作者回复: 大体如此

    2023-02-05归属地:上海
    5
  • ╭(╯ε╰)╮
    工作中经常遇到的问题: 1 技术上的泛化跟业务上的泛化不能很好的共存, 最常见的案例就是有个AbstractXXX的基(提取公共方法,封装技术实现比如把一类操作消息中间件的代码抽到父类里而产生的),另外有一个业务上归纳出来的父类。 因为不能多继承我的代码要么放弃技术上的抽象选择业务上的父类来继承,导致技术实现相关的代码到处复制粘贴。要么放弃业务上的父类,后果就是领域建模不能落地。 2 业务上的泛化使用技术不好实现(语言不支持多继承,接口不能有属性) 我是做游戏开发的,游戏设计各种天马行空,策划随便给过来一个技能,很可能就把之前版本的代码结构破坏掉,几十层的继承关系并不稀罕,各种散弹式修改和发散式修改。 身边不乏工作十几年的老程序员,但上面两个问题大家好像没有什么好的办法(或者他们习以为常不觉得这是问题),甚至很多屎山就是公司大牛的杰作。

    作者回复: 确实是常见的难题。 1 您所说的技术上的泛化(在实现层面,还是说继承吧),比如操作中间件的代码,其实不应该用继承,而应该用“组合”的思路,也就是把操作中间件的代码封装到类似 MqHelper 类中,然后依赖注入到使用它的类。所谓组合优于继承。把继承留给业务意义上的泛化。 2 即使只考虑业务意义上的泛化,也可能有多继承的问题。这时候要想办法,比如用策略模式来抽象算法,而不是在整个领域对象上运用继承。另一种思路是用接口实现部分意义上的多继承,而在接口的实现层面运用组合来模拟。几十层的继承关系肯定出不健康的,最好通过重构来优化。

    2023-02-06归属地:上海
    2
    2
  • 才华
    钟老师。请教一个问题,比如广告投放系统中,对于投放资源位,营销目标,推广标的等来说,不同的值决定了后续的业务逻辑判断和属性填充,这种的建议使用泛化还是特性值呢。

    作者回复: 不是很了解您的具体业务领域。大体而言,优先考虑在算法上进行泛化,比如说使用策略模式。

    2023-06-20归属地:北京
  • okokabcd
    领域模型的第三个关系,是不是可以理解成类和子类的关系啊?

    作者回复: 第二个才是类和子类的关系(类和子类都是类);第三个关系,是类和对象的关系。

    2023-02-21归属地:山东
  • 6点无痛早起学习的和尚
    思考题 2:2 个例子,但是感觉第一个例子不应该用泛化,第二个可以用泛化 第一: - 父类:账户项 - 子类:现金账户、备付金账户、待清算账户、待结算账户等等 共性:都有可用余额、冻结余额、挂靠会计科目等特性值 个性:业务规则不一样,子类的余额方向和交易方向对应出来的余额增减结果是不一样的,但是规则都是同增异减 第二:可以用泛化,但是最后用了策略 - 父类:正向交易 - 子类:支付、充值、提现 共性:业务规则流程相同,先校验参数、再校验是否原单和状态、组装请求外部参数、处理请求外部结果。 个性:每个子类的具体业务规则实现是不一样的。

    作者回复: 嗯嗯,第一个,如果个性只是业务规则不同,应该也可以用策略模式封装业务规则就可以了

    2023-02-20归属地:北京
    3
  • 赵晏龙
    1、没有进一步的需求,我觉得,不需要,用属性标识也够了。 2、 极客时间专栏、Java专栏/.Net专栏/Go专栏,这一类就不需要泛化,只有共性,没有特性 极客时间用户、企业用户/个人用户,这一类可能就需要泛化,如果企业用户和个人用户某些操作不同的话。 我感觉老师的帮我把知识梳理到底了,更清晰了。

    作者回复: 回答不错🐮

    2023-02-17归属地:湖南
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部