为什么领域模型对于架构师如此重要? https://blog.csdn.net/qq_40741855/article/details/84835212

2018年12月05日 14:30:19 绝圣弃智-零 阅读数 966
 

在信息化时代,人们在碰到问题的时候,经常会希望通过构建一套信息系统直接或间接的来解决问题。

比如说一家传统企业,在企业内部最常见的请假审批、费用报销审批这类的日常事务处理上,一开始碰到的问题是流程不够透明、员工不知找谁怎样处理,同时员工拿着纸质到处找各个审批人签字也费时费力。为此,企业通常会通过构建内部办公系统或报销系统,将流程固化透明,同时通过 app 等友好方式让员工和管理人员随时随地提交或审批请求,以此提高办公事务效率。接着还可能通过接口直接对接 HR 系统扣减员工年假天数,对接财务系统直接把报销款转账到员工银行工资账户里,以此来解决人工操作带来的人效问题,以及通过自动化减少人工失误问题。

再比如说,作为一家跨境电商企业,主要为中国消费者提供一个可以方便快速购买海外优质商品的平台。海外的不少商品,在品质、设计感、品牌内涵上,都胜于国内商品,消费升级的到来,国人已经适应并接受海外商品。并且多年来,国人已经养成购买全球母婴用品、化妆品、奢侈品、家居品等多种品类。但是在海淘过程中,国人因语言文化差异导致的对海外商品品类、价格、质量等信息的不对称,加上漫长且不透明的跨境物流递送等问题,都亟待解决。为此,从信息化角度我们会搭建 2C 电商平台来解决进口商品的国内销售问题,同时配套海外商家系统解决货源问题、物流相关系统解决履单物流配送问题等等。

总之,我们做任何一个软件系统,都是有原因的,都是要解决特定的问题的,否则就没必要做这个系统。所以通过问题,我们就知道了我们需要一个什么样的系统,这个系统解决了什么样的问题。而问题可以理解成是现状与预期的落差,这个落差就是真正需求的来源,于是最后我们就很自然的得出了一个目标,即知道了自己的需求是什么,通过做哪些事情来让未来达到预期。

接着我们引入比较抽象的两个概念:“问题空间(Problem Space)”和“解决方案空间(Solution Space)”,以此为后续领域建模提供工具支撑。所谓问题空间,简单理解就是当前环境下业务所面临的一系列问题和背后的需求,比如上述两个例子里的相关问题需求,它属于产品规划阶段,通常是业务或产品领域专家主导进行问题需求收集描述和分析;而解决方案空间则是针对问题空间的解决方案,它思考的是如何设计实现软件系统以解决这些问题,它属于工程设计实施阶段,通常是技术专家主导的解决方案设计和实现。因此,本质上,软件开发过程可以看做是问题空间到解决方案空间的一个映射转化。如下图所示。

在问题空间里,主要是找出某个业务面临的挑战及其相关需求场景用例分析,而解决方案空间里,则通过具体的技术工具手段来进行设计实现。因此上图还可以进一步细分成如下图所示的互联网软件从业人员容易理解的一个映射转化过程。

简单理解领域和领域模型

领域(Domain)”和“领域模型(Domain Model)”概念定义网络上可以查到很多解释,这里就不多说了。它们可以简单的这样理解:

  • “领域”相对于软件系统来说,就是系统要解决的现实问题。因此也可以简单理解一个领域就对应一个问题空间,是一个特定范围边界内的业务需求的总和。

  • “领域模型”则是针对特定领域里的关键事物及其关系的可视化表现。它属于“解决方案空间”,是为了准确定义需要解决问题而构造的抽象模型,为软件系统的构建目标统一认知,是业务功能场景在软件系统里的映射转化。

比如上面的例子里,请假系统解决的问题是人力工时的问题,属于人力资源领域,对口的业务 Owner 是 HR 部门;费用报销系统解决的是员工和公司之间的财务问题,属于财务领域,对口的业务 Owner 是财务部门;跨境电商牵涉范围甚广,但本质上还是属于电商领域。同时可以看出,每个软件系统本质上都解决了特定的问题,都属于某一个特定领域,都实现了同样的核心业务功能来解决该领域里最核心的业务需求。比如电商平台、普通电商系统,这些都属于电商领域,只要是这个领域的系统,都会有商品浏览、购物车、下单、减库存、支付等核心环节。所以,同一个领域的系统都具有相同的核心业务,因为他们要解决的问题的本质是类似的。而之所以每个电商平台之间又有不同,那是由于客户群体、经营策略、商品种类、定价策略等不同而造成的差异。所以才有这样的说法:领域来自于需求,但它却高于需求,相对于善变的需求而言,领域知识和领域模型本身是“静止”的,是“不变”的。

领域建模分为“战略建模”和“战术建模”两个层面,建模方法论也有多种,这里就不再累述。要对领域进行建模得到优秀的领域模型,必须先要对行业领域的业务有比较深入的理解,才能从复杂环境中找出领域核心问题,然后对它展开梳理。通常来说,一个领域有且只有一个核心问题,我们通常称之为该领域的“核心子域”。领域的战略建模通常就是从找出核心子域开始的。其次,在核心子域及通用子域和支撑子域梳理的同时,会定义出子域中的 Bounded Context(限界上下文)及其关系,用它来阐述子域之间的关系。最后,就是找出每个子域中的关键领域实体进行抽象提炼,并根据业务本质找出它们之间的联系关系。

为什么要建模?因为建模是帮我们提炼出事物的本质,以便能更好的指导应用系统规划建设。看一个简单例子。企业信息化规划建设经常谈到“人、财、物”的整体管控,对于“人”这部分,从大部分行业业务角度建模,可以归纳成经典的“三户模型”,即客户、用户、账户三户模型。

其中,客户是指现实中的一个自然人或法人机构;用户则是客户在使用信息系统时对应的实体,我们常称之为系统帐号;账户是客户存放个人资产资金的实体,相较于线下银行金融机构里的实际账户,线上交易支付相关应用里的又称为虚拟账户,存放虚拟货币、积分、甚至是实际货币。三户的关系在百度百科里说的比较好,它是这么说的:这三者之间的关系应该是一个相互关联但又是独立的三个实体,这种关联只是一个归属和映射的关系,而三个实体本身是相互独立的,分别是体现完全不同的几个域的信息,客户是体现了社会域的信息,用户体现了业务域的信息,账户体现的是资金域的信息。三户模型最早是在电信运营领域里提出的,后来在银行、金融、第三方支付、电商等各领域得到了广泛应用。

案例:酒店管理系统 PMS

一家酒店在日常管理中的方方面面,包括客房管理、预订处理、客人入住和退房办理、在住客人的服务等,在行业里通常是由 PMS 系统来一手包办。当然大型酒店集团,还会针对每个环节有更深入的应用,比如中央预订系统来处理各种渠道的预订订单、CRM 处理酒店会员关系管理、房价体系系统实现动态定价、房控系统实现客房资源利用最大化等等。但回归到核心,所有酒店都共有的核心,可以归纳为下面的核心业务流程:

核心业务流程具体描述如下:

  1. 客户选择预订渠道下订单:客户可以选择预订渠道预订酒店连锁集团下的任一酒店,包括从官网、 app、中介 OTA(如携程网等)、呼叫中心进行预订,也可以直接步入酒店在酒店前台当场进行预订。PMS 根据客户在某时间段里需要入住的酒店和房型,结合其可用房数量和当时的房间房价进行下预订单操作。预订单一旦生成,房态会发生变化,可用房数量也发生变化,最终结账的房价为当时下预订单时的房价。

  2. 住客入住接待:住客根据预订的时间来到预订的酒店办理入住。前台根据住客提供的身份证等信息办理入住,PMS 根据入住信息生成接待单,并将房卡制好发给住客。住客根据制好的房卡入住指定的房间。

  3. 住客服务接待:住客在入住期间,可以享受酒店提供的一系列礼宾服务和餐娱乐服务,比如叫醒服务、早餐服务等。每次服务接待都应在接待单里产生相应的接待服务信息;如果接待服务为收费项目时,比如餐饮服务,则需要同时进行账务处理,加入账单流水账中。

  4. 夜审:夜审主要是做入账对账及其核查。每次夜审都应该将住客房费和餐娱乐等费用进行核查,最终算入当日营业日业绩。只有夜审完成后,系统才能进行下一营业日的酒店营业操作。

  5. 住客退房:住客退房时,系统需要对住客在入住期间的所有服务及其费用进行核查结算,在满足退房条件的情况下,回收房卡,并更改房间房态。

  6. 客历归档:住客从入住到退房整个过程,默认将收集到的住客在期间的喜好和反馈存入住客档案中,供后续进行客户分析和客户个性化服务使用。

酒店的核心业务是稳定可扩展的,不随市场活动等外部日常运营业务而不断变化。因此 PMS 中,日常运营业务的变化,如市场活动对房价造成的影响,或餐娱乐服务对住客账单的影响等,都是与核心业务剥离弱化关联的,以此保证核心业务稳定沉淀的同时,系统仍然可以多变适应日常运营业务灵活多变的需要。

在理解酒店核心业务后,顺理成章可以得到酒店管理领域的核心子域——客房管理子域。这是因为酒店的所有核心业务都围绕着客房管理进行的。比如,预订房间时,最重要的是了解这家酒店的可用房信息及其相关房价、客人入住时需要关联房间并变更房态、酒店服务的收银账务是按房间来进行挂账买单的等等。以此为核心,通过 Bounded Context 关联各个相关子域。如下图所示:

领域中的界限上下文可以简单理解成一个子系统或组件模块,它放在哪个子域里最为合理是受到场景制约的。有时候,同样一个业务甚至同一个实体,会出现在不同的子域里,结合该子域的上下文来进行不同的描述。领域和界限上下文的划分并没有标准,它是依据每个人对特定业务不同程度的理解和抽象程度而不同的。评判一个领域模型是否合理,只能放到特定的业务背景和场景下才会相对客观。

最后根据上述战略建模的结果,进行领域模型上的战术建模。根据核心子域里的界限上下文及核心场景,抽象出领域实体及其关系,并用概念类图的方式呈现出来。这张领域模型图也有很多的画法,但最重要的是要让业务和技术等各方干系人都能理解这张图表达的涵义,以此形成统一的共识。领域模型图怎么画并不是关键,最关键的是明白领域模型要解决什么问题, 然后才能把这个问题毫无歧义的表述成一张图来凝结各方共识。战术建模得到的领域模型图,其关键就是识别出各类关键实体,以及它们之间的关系;而最终领域模型的验证反过来也是通过战略模型和核心业务场景流程来验证的。下图是酒店管理领域模型图示例。

思考总结

领域建模不是面向技术的一种纯软件设计方法,它是一种思维方式,我们采用它来搭建领域模型,以此弥补业务和代码之间的 Gap,促进团队合理的分工协作,同时也时刻真实的反映着我们所要解决的问题的变化,让我们构建的系统富有价值和生命力。

所以,领域模型的价值不在于它的设计优美﹐而在于它体现了系统的核心价值。那么什么是系统的核心价值?一个企业内部常用的费用报销系统和一个互联网的大型支付系统,它们本质的区别不是用了什么编程语言,也不是用了什么数据库,而是其提供的服务及其服务质量,也就是我们最开始所说的,它能解决的问题及解决的程度。

为什么领域模型对于架构师如此重要? https://blog.csdn.net/qq_40741855/article/details/84835212的更多相关文章

  1. 程序员的沟通之痛https://blog.csdn.net/qq_35230695/article/details/80283720

    个人理解: 一般刚工作的程序员总觉得技术最重要.但是当工作年限超过3年.或者岗位需要涉及汇报.需求对接等就会发现沟通非常重要.也许在大公司还不那么明显,但是在小公司.小团队或者创业,沟通甚至可以说是第 ...

  2. 手把手教你如何玩转消息中间件(ActiveMQ) https://blog.csdn.net/cs_hnu_scw/article/details/81040834

    #情景引入小白:起床起床起床起床....快起床~我:怎么了又,大惊小怪,吓到我了.小白:我有事有事想找你,十万火急呢~~我:你能有什么事?反正我不信..那你说说看~~小白:就是我有两个小表弟,叫大白和 ...

  3. https://blog.csdn.net/u011489043/article/details/68488459

    转自https://blog.csdn.net/u011489043/article/details/68488459 String 字符串常量   StringBuffer 字符串变量(线程安全) ...

  4. https://blog.csdn.net/uftjtt/article/details/79044186

    https://blog.csdn.net/uftjtt/article/details/79044186

  5. 自动车牌识别(ALPR)---https://blog.csdn.net/ELEVEN_ZOU/article/details/80893579

    1.基本功能:从一张或者一系列的图片中提取车牌信息,比如车牌号码.车牌颜色等信息. 2.功能扩展:车型.车品牌.车牌类型等. 3.应用方向:电子交易系统(停车自动收费.收费站自动支付等).交通执法.交 ...

  6. Nginx 配置location root 转自https://blog.csdn.net/rofth/article/details/78581617

    nginx指定文件路径有两种方式root和alias,root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上. 最基本的区别 ...

  7. golang操作memcached 转自https://blog.csdn.net/weixin_37696997/article/details/78760397

    go使用memcached需要第三方的驱动库,这里有一个库是memcached作者亲自实现的,代码质量效率肯定会有保障 1:安装 go get github.com/bradfitz/gomemcac ...

  8. 爬虫出现Forbidden by robots.txt(转载 https://blog.csdn.net/zzk1995/article/details/51628205)

    先说结论,关闭scrapy自带的ROBOTSTXT_OBEY功能,在setting找到这个变量,设置为False即可解决. 使用scrapy爬取淘宝页面的时候,在提交http请求时出现debug信息F ...

  9. https://blog.csdn.net/doegoo/article/details/50749817

    因为使用DiscuzX3.2进行系统的整合后,因为只是想在原J2EE的系统上增加论坛功能,而且J2EE中已经有一套用户的注册认证的体系,所以不需要在Discuz的系统中去注册以及登录功能,而是通过在J ...

随机推荐

  1. 转换为CString

    CString a, b, c;c = a + b; 使用Format方法方便的实现int.float和double等数字类型转换为CString字符串. %c 单个字符 %d 十进制整数(int) ...

  2. Android 定义和使用样式

    如图,在stryle.xml中定义样式 然后可以在布局文件中使用样式

  3. delete 删除指针

    危险的代码: int* p=new int(1);   delete p;   delete p; 安全的代码: int* p=new int(1);   delete p;   p = NULL; ...

  4. 算法习题---3.08循环小数(UVa202)

    一:题目 输入整数a和b(<=a<=,<=b<=),输出a/b的循环小数表示以及循环节长度. 例如,a=,b=,小数表示为0.(),循环字节长度为21 当循环节长度超过50时, ...

  5. Elasticsearch(ELK)集群搭建

    一.前言 Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储.检索数据:本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据.Elasticsearch也使用 ...

  6. Django中使用Bootstrap----带view.py视图函数(也就是项目下的脚本文件)

    一.Django中使用Bootstrap 1.首先建立工程,建立工程请参照:https://www.cnblogs.com/effortsing/p/10394511.html 2.在Firstdja ...

  7. C入门笔记

    教程总体概括:Mac OS X系统简介:C语言:OC语言:Foundation:iOS开发:项目实战. 3.第一个c语言程序#include <stdio.h>//预处理指令:在编译之前执 ...

  8. C#RSA加密解密(对接PHP)

    上篇文章中写的RSA加密是针对C#的,现在外部调用的是PHP,我们平常见到的RSA无论公钥和私钥都是一长串数字,很显然C#生成的XML不是通用的加密.如果外部调用需要处理一下. 一.首先可以去网上找一 ...

  9. 做了一个非竞价排名、有较详细信息的程序员职位 match 网站

    作为一个程序员,每次看机会当我去 BOSS 直聘 或者拉勾网进行搜索时,返回的顺序并不是根据匹配程度,而是这些公司给 BOSS 直聘或者拉勾网付了多少钱.这种百度式的竞价排名机制并没有把我做为求职者的 ...

  10. 【VS开发】fatal error C1001:编译器中发生内部错误

    自己编译boost的库文件时遇到这个错误的,大概报错情况如下:  mp_defer.hpp<50>:fatal error C1001:编译器中发生内部错误.  1> 要解决此问题, ...