域模型在交流中扮演的角色

简介: 域模型在交流中扮演的角色

问题:我对于领域模型如何表示始终还不太明白。按照Evans书里的说法,代码应当是领域模型的主要部分,文档、图表作为补充。另外一方面,领域模型应当是所有参与者都能够理解的,而我觉得用户不太可能去理解代码。


比如以Evans书里举的,可以超载10%这一点,书里是通过一个Strategy模式来表达这个知识,从程序员的角度看很清晰了,但是从用户的角度看,还是不太能够明白吧。


请教张老师如何看待这个问题?


回答:其实从模型的角度看,有几个层次,Eric说的是模型驱动模型。重点是模型。这几个层次包括:

  • 现实模型即问题域
  • 领域模型
  • 设计模型
  • 代码模型


实际上领域模型是搭建现实模型需求问题到解决方案的桥梁。领域模型是领域概念尤其是统一语言的可视化表现,在Eric写作《领域驱动设计》一书的时代,领域模型多数以UML来表达。


这里要注意一个历史问题。在Eric写作该书的时代,正是UML与逆向工程大行其道的时代。当时有很多人都在倡导运用建模工具如Rational Rose来建模,进而利用图形化的模型生成代码。这个思想在当时人们的心中会是未来编程的一个主流发展方向,也有很多人在朝着这个方向努力,随之也催生了诸多建模工具的诞生,UML得到大量的普及,甚至差点成为了软件设计的唯一标准。这也是Eric倡导模型驱动设计的一个历史背景,至少我认为他在写书时是收到这个思想影响的。最终,这种设计思想并没有得以实现,人们低估了编程的复杂度,高估了模型的重要性。所以,Eric的书是有历史局限性的。尽信书不如无书,这是阅读他的书要注意的。书中讲的一些实践,未必都对。


但是,Eric的领域驱动设计是一个方法学,是开放的,也是逐步演进的。事实上,已经有很多人站在Eric的肩膀上,提出了很多切合实际,也吻合软件行业发展趋势的实践与模式,作为领域驱动设计的补充。例如领域事件、六边形架构以及CQRS等。Eric自己也认可这种演进。


回到模型上来。我认为领域模型就是对领域概念的抽象,你说的超载10%其实就是业务规则,所以可以抽象为一个领域概念,在与领域专家进行交流时,可以通过领域模型的这个领域概念来表达,而不是直接使用代码。


设计模型则是对领域模型的一种技术呈现,乃至于是从技术角度的一种精化与演进,例如通过引入设计原则与模式,可以实现领域模型对象更好的职责分配,通过抽象实现解耦,定义更加合理的封装。这时,设计模型要取决于你的编程范式,如采用面向对象还是函数式编程。同样以超载规则为例,面向对象范式的设计模型就是抽象的服务接口,函数式就是一个函数。如果规则需要组合,前者就利用继承或委派,后者就用组合子。


代码模型是设计模型的具体实现,它是遵循设计模型来实现的,采用不同的语言和框架,也会有区别。例如,有的语言可以非常方便地定义值对象,如Scala的Case Class,就是值对象的语法糖。


整体来看,领域模型是团队与领域专家交流所用,设计模型是团队的设计人员交流的工具,代码模型自然为程序员服务。这三个模型之间的关系如下图所示:


image.png


随着时间的推移,这三种模型可能会出现不同步的问题。Eric在书中讲解模型驱动设计时也提到了这个问题。如上图所示,领域模型为指导设计模型,设计模型是领域模型的实现,而随着设计模型的演进,我们又需要这种变更体现在领域模型中,保证模型是领域的真实表达。至于代码模型,一方面是遵循设计模型进行代码的实现,同时还应该尽力保障代码模型要表达领域概念,这不仅仅是从代码可读性的角度来考虑,也牵涉到代码对领域逻辑的呈现。这也是为什么在DDD的编程实践中,我们为什么希望避免贫血模型,希望避免使用无法表达领域行为的get和set方法的原因。


倘若要在代码模型中体现领域模型,一种更好的做法是使用DSL,即领域特定语言。但DSL的实现其实是一个相对漫长的积累过程,不同语言的领域表达能力也不相同。所以DSL主要还是用在一些相对复杂但又相对稳定专业的行业中,例如通信和金融行业,就有DSL的开发需求。当然,即使不去做一套DSL,我们也可以借鉴DSL的思想,例如通过Fluent Interface之类的实践改进代码的表达能力。


还有一种做法就是利用BDD编写验收测试,形成活文档(Live Document)。BDD框架如Cucumber、Robot Framework、RSpec其实就是一种DSL,通过这些框架可以编写符合自然语言规范的测试用例,形成一个中规格(Specification),这些测试用例又是能够运行的代码,这就相当于搭建了代码与需求规格的桥梁。不过,这种活文档只能应用在测试保障上,它可以帮助我们建立一种更好的交流机制,但并不能取代设计模型和代码模型。

相关文章
|
21天前
|
运维 安全 Serverless
函数计算产品使用问题之要配置 role(服务角色),该如何进行操作
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
26天前
|
存储 搜索推荐 索引
开发与运维数据问题之Retrievers在LangChain中扮演角色如何解决
开发与运维数据问题之Retrievers在LangChain中扮演角色如何解决
17 0
|
3月前
|
安全 项目管理 数据安全/隐私保护
角色扮演:项目管理软件中角色的定义与创造性构建
项目管理软件中的角色用于设定用户权限和职责,确保团队协作有序且信息安全。常见角色包括管理员、项目经理、团队成员、客户、观察员和审核者,各自承担不同任务。创建角色通常需要管理员权限,步骤包括登录设置、新建角色、设置权限和访问范围,然后保存和分配。合理的角色分配能有效提升项目管理效率。
87 1
|
8月前
|
人工智能 图形学
AI角色对环境信息的感知方式
AI角色对环境信息的感知方式
|
SQL 人工智能 数据可视化
Prompt learning 教学案例篇:文生文案例设定汇总,你可以扮演任意角色进行专业分析
Prompt learning 教学案例篇:文生文案例设定汇总,你可以扮演任意角色进行专业分析
|
领域建模 图形学
3D角色建模师和3D角色动画师哪个更有前景?哪个更适合小白入门?
我的建议是:先学3D角色建模,掌握后找一份3D角色建模的工作先做着,然后慢慢学动画!
269 0
3D角色建模师和3D角色动画师哪个更有前景?哪个更适合小白入门?
|
监控 安全 Serverless
白话讲解函数计算中的角色授权
初次入坑函数计算的小伙伴,遇见的第一大拦路虎非RAM授权相关莫属。开始玩玩`hello world`这种无关授权访问其他阿里云资源的时候,感觉 serverless 大法各种好,之后发现线上排查问题日志的时候,第一次给service配置role的时候,虽然控制台能成功配置,但是估计也是一脸懵逼。
3602 0