Eswlnk Blog Eswlnk Blog
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈
  • 注册
  • 登录
首页 › 热议话题 › 「热议话题」DDD的哲学:模型的关联、演进和认知

「热议话题」DDD的哲学:模型的关联、演进和认知

Eswlnk的头像
Eswlnk
2022-12-30 20:05:17
「热议话题」DDD的哲学:模型的关联、演进和认知-Eswlnk Blog
智能摘要 AI
本文探讨了领域驱动设计(DDD)中的关联建模、模型演进及限界上下文,结合哲学与科学理论进行阐述。首先,强调关联在领域建模中的重要性,指出关联的数量关系(如一对一、一对多)需被细致识别,否则模型不完整。接着,讨论了模型演进的必要性,提出采用演进式架构,借鉴进化论的“遗传”“变异”“适者生存”原则,实现增量、多维度、导向性的架构变化。最后,分析限界上下文的实质,指出其源于人类认识能力的有限性,通过分而治之的方法确保局部一致性,避免全局一致性的不可行性。综上,本文强调了关联建模、模型演进和限界上下文在复杂系统中的关键作用。

“关联”、《矛盾论》、毕达哥拉斯学派

前面说到了“模型驱动的设计”以及其中两个重要的模式“实体”和“值对象”,两者统称“领域对象”。在领域建模的过程中,建立领域对象间的“关联(Association)”也是非常重要的。《DDD》第5.1节对此进行了专门的讨论。不过与实体不同,艾老师并没有把关联当做一种正式的“模式”。这一点实属可惜,因为关联至少与实体有同样的重要性。为什么这么说呢?下面还是先扯几句哲学。

「热议话题」DDD的哲学:模型的关联、演进和认知-Eswlnk Blog

前面提到毛老师的《实践论》,这里再说说怹老人家的另一篇杰作《矛盾论》。这篇论文的第一部分“两种宇宙观”中提到了两种认识论体系:“形而上学”和“唯物辩证法”。前者是错误的、后者是正确的。

形而上学认为事物的发展是静态的、外因驱动的、孤立的;唯物辩证法则认为事物的发展是动态的、内因驱动的、联系的(还记得中学政治课背过吗?)。前两点我们后面再聊,这里先讨论“联系”。

《矛盾论》中引用列宁的话:“要真正地认识事物,就必须把握住、研究清楚它的一切方面、一切联系和‘中介’。我们永远也不会完全做到这一点,但是,全面性这一要求可以使我们防止犯错误和防止僵化。”这强调了,只有充分了解事物之间的联系,才能充分认识事物。

DDD中,领域(事物)的概念以实体、值对象、聚合、模块等方式表达出来。有些伙伴把领域中的主要聚合或实体识别出来后,却没有识别它们之间的关联,就认为已经完成了领域建模。这样的模型其实是不完整的。那么,如果我们认识到了这一点,并且识别出了关联之后,还要进一步识别关联上的哪些信息呢?让我们先看一下古老的毕达哥拉斯学派。

这个学派在古希腊最早对数学进行了系统的研究。他们发现了无理数,然后把泄露无理数秘密的团队成员扔进了大海。毕达哥拉斯认为世界的本原是“数”。宇宙的和谐来源于数的和谐。而数的和谐体现在十组对立的关系中:一与多、奇与偶、左与右、阴与阳、动与静、曲与直、明与暗、善与恶、方与长、有限与无限。在这十组关系中,最根本的是“一与多”。也就是说,只有把握了“一与多”,才能把握“数”,进而把握世界。

从毕达哥拉斯的学说中,我们或许可以得到这样的启发(嗯 ~ ~ 我承认有点牵强):在领域模型中,对关联进行建模时首先要考虑的是数量关系。也就是常说的“一对一”“一对多”“多对多”等等。如果做得精细些的话,还可以考虑存在性(必选的还是可选的)。不少建模人员在建模时都忽视了理清数量关系,从而限制了对领域知识的深刻理解。

对数量关系的识别看似简单,但我们发现百分之六七十的初学者在实践中都会搞错。只有经过一段时间的练习,才能充分掌握。

此外,前文提过,除了这里说的实例之间的关联以外,还要考虑类型之间的关联(也就是泛化)。对泛化关系的掌握,是领域建模技术从初级阶段迈向中级阶段的门槛,也是向高级建模技术进阶的关键。要熟练掌握这项技术,除了在项目中实践,还可参考《分析模式》。在《DDD》的后半部分有一些高阶的例子运用了泛化,但在前面讲模型驱动设计的章节却没有提及泛化,这就忽略了一种建模的重要手段,也算是该书的一个瑕疵吧。

模型的演进、辩证法、进化论

前文说到,唯物辩证法认为事物的发展是动态的、内因驱动的、联系的;并且已经讨论了“联系”。这一节首先讨论“动态”。

事物的发展变化是永恒的。因此,我们会不断强调,与其期望一次性把领域模型和架构建好,不如建立团队的架构演进能力。在《DDD》第8章至第13章,集中讨论了模型重构的方法。

模型要不断演进,这个说法多数人听了都会点头称是。又有谁不知道“唯一不变的就是变化”呢?然而在这一点上,说到和做到是有距离的。

真想做到模型的演进,不仅需要上述《DDD》中的建模技能,还要扎实地掌握重构、TDD(或者至少是自动化测试)和持续集成,我将之称为敏捷工程实践的“老三样”。此外,还要掌握架构演进和数据库演进的若干种模式,以及建立多维度的指标体系,利用工具进行量化的架构守护等。

然而我们很多人,哪怕接受了DDD,也是急于学习建模技能(这本身没有错),而对模型演进丝毫不感兴趣。这样的DDD往往半途而废。这是因为,如果不能演进模型(进而演进整个软件系统),那么软件和模型就会逐渐不一致,最后模型变成废纸一张,一切打回原形。这背后可以回归到团队甚至企业文化的问题。衡量一个企业的文化,关键不是看怎么说,而是看怎么做。

谈完“动态”,再谈“内因驱动”。

《矛盾论》中强调“唯物辩证法认为外因是变化的条件,内因是变化的根据,外因通过内因而起作用”。内因是第一位的,外因是第二位的。而形而上学只看到外因,外因也能使事物发生变化,但只是量的变化。而内因才能导致质的变化。换句话说,事物本身必然包含内在的矛盾,这一矛盾的发展变化,在一定外因的条件下,会导致事物发生质的变化。

联系到模型的演进,我们从《DDD》中的相关例子看到,随着对领域知识理解的深入,模型的重构往往不是多了几个实体、少了几个关联,而是多出了若干抽象层次,甚至将模型的核心部分打碎重组。所以我们既要对这一点有充分的心里准备,知道这是复杂系统的模型演进中必然发生的;也要未雨绸缪,掌握相关的建模和架构演进技术。不过也不用怕,当掌握相关技能后,再复杂的重构,总可以小步快跑,稳健推进。

前面反复提到了架构演进。其实《DDD》和《演进式架构》是两本书。两者的侧重点不同,一本侧重领域建模,一本侧重系统架构演进。不过在实践中我们常常将两者结合起来运用。下面聊两句演进式架构的原理,这超出了《DDD》原书的范围。

“演进式架构”强调增量地、多维度地、导向性地架构变化过程。我们主要解释这三个关键词。

《演进式架构》(Building Evolutionary Architectures)和“进化论”(Theory of Evolution)中的“演进”和“进化”其实是同一个英文词根。有人将“Theroy of Evolution”翻译成“进化论”,有人翻译成“演化论”。《演进式架构》的译者讨了个巧,各取一个字,就成了“演进”,其实都是一个意思。所以,演进式架构实际上引用了进化论的隐喻。

达尔文的《物种起源》将进化论总结为遗传、变异和适者生存。该书第一部分首先讲的是“人工选择”,例如对狗和金鱼的驯化;后面才推广到自然选择。将演进式架构和进化论进行比较,可以看到一些有趣的共同点。

将软件系统类比为生命体。不影响系统架构的渐进式修改相当于生物的“遗传”。对架构的本质性修改相当于生物的“变异”。变异的系统需要经过各种验证,看看是否符合人的需求,这实际上是一种“人工选择”的过程。适应需求的架构得以延续,不适应的则会被淘汰或进一步变异,这就是演进式架构中说的“导向性”,也这就是“适者生存”。达尔文指出物种的进化总是渐进式的,而不会短时间内发生剧烈变化。这就是演进式架构中的“增量式”变化。生物适应环境时,要适应多方面的因素:捕食能力、逃避天敌的能力、适应气候的能力、抵御病虫害的能力、繁殖能力等等。各种因素都适应,才能生存。同样,系统也要适应多方面的因素:功能的正确性、可扩展性、可维护性、性能、安全等等。这就是演进式架构中说的“多维度”。

上述类比可以促使我们对演进式架构进行更深入的思考。至于具体技术,可以参阅原书。

限界上下文与人类认识能力的有限性

虽然哲学家可能是人类有史以来最喜欢争辩的群体,但有一个观点,多数哲学家却是有共识的:人的认识能力是有限的。从孟子的“吾生也有涯,而知也无涯”,到康德的“物自体不可知”,再到辩证唯物主义的“人只能认识相对真理”,都说明了这一点。那么,这和限界上下文有什么关系呢?

如果问一位同事限界上下文是什么,常常听到这样的回答:“业务功能的边界”“业务领域的边界”诸如此类。这种说法虽然没错,但说的是结果,不是原因;是表象,不是本质。因为聚合、模块等也可以说是一种“业务功能的边界”。所以上述回答没有答到点子上。

限界上下文是在《DDD》第14章“保持模型的完整性”中介绍的。眼尖的同学可能就会问了:为什么这一章的名字不叫做“划分功能边界”?这里的“完整性”到底指什么?

让我们继续看原文。这一章的开头几段所举的例子,是说有两个团队共用了一个Charge(收费)对象。但两个团队所说的Charge背后的业务概念其实是有差别的。开始时两个团队都没有意识到这个问题。他们都去改这个类,后来程序崩溃了。然后作者说“模型最基本的要求是它应该保持内部一致,术语总具有相同的意义,并且不包含互相矛盾的规则……”。所以,作者在本章要解决的实际上是系统的一致性问题。

这一章标题中的“完整性”是对单词Integrity的翻译。Integrity固然有“完整性”的意思,但也包含“统一”、“健全”等含义。因此,本章的标题如果翻译成“保持模型的统一”会更准确。翻译成“完整性”则容易造成误导。

保持系统的一致性,早已被IT界的前辈们所重视。例如,Brooks老师在七十年代写的《人月神话》中已经做了强调。不过,之前的专家们在潜意识里总是认为,对于一个复杂的系统,总有办法做到团队理解的全局一致性。《人月神话》中就列举了若干种方法。

然而《DDD》中指出“在理想世界中,我们可以得到涵盖整个企业领域的单一模型。这个模型将是统一的,没有任何相互矛盾或相互重叠的术语定义”然而“大型系统领域模型的完全统一既不可行,也不划算”。

为什么“不可行”呢?答案就是人类认识能力的有限性。由于大型软件是团队协作开发的,因此这里的认识能力还要扩展到群体的认识能力。也就是包含了个人的认识能力、群体的协作能力、以及两者的相互作用。越是复杂的系统,认知起来越困难。当系统复杂性达到一定程度时,就超过了一个团队的认知能力,无法保证系统的一致性了。

解决的办法就是分而治之,将一个“理想中”的大模型划分成几个小模型,每个小模型不超过团队的认知能力。因此每个小模型内部就可以保证严格的一致性,而与另一个模型内部不需要一致,只需要约定好模型之间的接口就可以了。也就是说,我们在了解了人类认识能力的有限性之后,不再追求全局一致性,而是退而求其次,代之以局部的一致性,从而使系统的正确性在总体上得到管理,实现业务目标,这样就足够了。

概念的一致性是通过语义上的一致性来表达的,所以作者引用了语言学上“上下文”的术语。在日常语言中,人们常常会随时切换上下文,在特定场景下未必会影响沟通。但在计算机软件中,一个元素要么属于一个上下文,要么不属于,这个界限必须清清楚楚。为了强调这一边界的重要性,因此称为“限界上下文”。

上下文的具体划分方法,仍然要围绕领域概念的内聚和耦合关系。因此划分的结果,当然表现了一个“领域的边界”或者说“功能的边界”。如上文所述,这是结果而不是原因。

根据敏捷组织的理论,一个开发组的规模最好在5~9人之间(这是有心理学研究作为依据的)。那么,一个限界上下文的规模,一般就是这样一个开发组所能把握的规模。

知道了人类认识能力的局限,就使我们对这个世界秉持谦卑和敬畏的态度。这也有助于我们理解限界上下文所要解决的问题、划分的方法、及其与团队的关系。最终使我们能够正确划分上下文,管控好复杂系统的一致性。

在这个系列文章的最后一篇,我们将继续讨论“核心域”、“统一语言”,并对全文做一个总结。

本站默认网盘访问密码:1166
本站默认网盘访问密码:1166
声明:本站原创文章文字版权归本站所有,转载务必注明作者和出处;本站转载文章仅仅代表原作者观点,不代表本站立场,图文版权归原作者所有。如有侵权,请联系我们删除。
哲学日志
0
0
Eswlnk的头像
Eswlnk
一个有点倒霉的研究牲站长
赞赏
「热议话题」数据驱动体验度量的挑战与思考
上一篇
「科技资讯」苹果12怎么分屏?
下一篇

评论 (0)

请登录以参与评论
现在登录
    发表评论

猜你喜欢

  • 「日志」IG无缘S15总决赛
  • 来自谷歌27岁的生日涂鸦
  • 科研记录:ecCodes处理grib文件问题
  • 本站上线邀请码免费兑换系统
  • 漏洞资讯:Ollama 未授权访问漏洞分析与防护指南
Eswlnk的头像

Eswlnk

一个有点倒霉的研究牲站长
1108
文章
319
评论
679
获赞

随便看看

新型 Android 恶意软件 CherryBlos
2023-07-29 17:36:07
无代码网站有哪些优势和劣势
2022-08-10 11:18:59
iOS 零日攻击揭秘:探索三角测量行动的更深层内幕
2023-10-24 22:40:02

文章目录

专题展示

WordPress53

工程实践37

热门标签

360 AI API CDN java linux Nginx PDF PHP python SEO Windows WordPress 云服务器 云服务器知识 代码 免费 安全 安卓 工具 开发日志 微信 微软 手机 插件 攻防 攻防对抗 教程 日志 渗透分析 源码 漏洞 电脑 破解 系统 编程 网站优化 网络 网络安全 脚本 苹果 谷歌 软件 运维 逆向
  • 首页
  • 知识库
  • 地图
Copyright © 2023-2025 Eswlnk Blog. Designed by XiaoWu.
本站CDN由 壹盾安全 提供高防CDN安全防护服务
蜀ICP备20002650号-10
页面生成用时 0.537 秒   |  SQL查询 48 次
本站勉强运行:
友情链接: Eswlnk Blog 网站渗透 倦意博客 特资啦!个人资源分享站 祭夜博客 iBAAO壹宝头条
  • WordPress142
  • 网络安全64
  • 漏洞52
  • 软件52
  • 安全48
现在登录
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈