阅读笔记-领域驱动设计-第八章--建模突破

本章主要讲解一个真实案例中的领域驱动的建模,逐步去突破深层次的模型,一步步的修改设计,慢慢优化。

重构的投入与回报并非呈线性关系。通常,小的调整会带来小的回报,小的改进也会积少成多。小改进可防止系统退化,成为避免模型变得陈腐的第一道防线。但是,有些最重要的理解也会突然出现,给整个项目带来巨大的冲击。

可以确定的是,项目团队会积累、消化知识,并将其转化成模型。微小的重构可能每次只涉及一个对象,在这里加上一个关联,在那里转移一项职责。然而,一系列微小的重构会逐渐汇聚成深层模型。

  • 一般来说,持续重构让事物逐步变得有序。代码和模型的每一次精化都让开发人员有了更加清晰的认识。这使得理解上的突破成为可能。之后,一系列快速的改变得到了更符合用户需要并更加切合实际的模型。其功能性及说明性急速增强,而复杂性却随之消失。

这种突破不是某种技巧,而是一个事件。它的困难之处在于你需要判断发生了什么,然后再决定如何处理。为了说明这是种什么样的经历,这里将展示讲述一个笔者几年前参与过的真实项目,以及他们是如何获得一个宝贵的深层模型的。

一、一个关于突破的故事

背景:这个故事发生在纽约,经过一个冬天的漫长重构之后,我们最终得到了能够捕捉到一些领域关键知识的模型和一个确实能在应用程序中发挥作用的设计。当时我们正在给一家投资银行开发一个大型应用程序的核心部分,该程序用于管理银团贷款。

假如Intel想要建造一座价值10亿美元的工厂,就需要申请贷款,但贷款的额度太大,以至于任何一家借贷公司(lending company)都无法独立承担,于是这些公司就组成银团①,集中它们的资源,以此来支持这种巨额信贷。投资银行通常在银团里担当领导者的角色,负责协调各种交易和其他服务。我们的项目就是要开发这样一个用于跟踪和支持以上整个过程的软件。

当时,我们对于自己的成果感觉相当不错。4个月前,我们还身陷困境,因为之前留下的代码完全不可行,从那时开始我们就竭尽所能将其迁移到一个一致的MODEL-DRIVEN DESIGN中。

图8-1中展示的模型对常见业务进行了大幅简化。Loan Investment(贷款投资)是一个派生对象,用来表示某一投资者在Loan(贷款)中所承担的股份,它与投资者在Facility(信贷)中所持有的股份成正比。
图8-1 假定放贷方股份固定的模型

inverstment(投资)
investor (投资者)
① 借贷公司(lending company)对于借款者(borrower)而言是放贷方(lender),对于银团而言是投资者(investor)。

但是这个模型已显露出了一些令人担忧的迹象。各种意料之外的需求一直困扰着我们,也使设计更加复杂。最突出的例子就是对Facility股份的理解不断深入,在提取(Drawdown)贷款时,信贷股份仅仅是放贷方投入金额的指导原则。当借款者(borrower)要求提取贷款时,银团领导者会通知所有成员按各自的股份进行支付。

收到通知后,投资者通常会按自己的股份来支付,但是有时他们也会与银团其他成员协商,以求少投入(或多投入)一些。于是我们在模型中添加了Loan Adjustment(贷款调整)以反映这一事实。


图8-2

这种类型的精化使我们能够越来越清楚地理解各种交易规则。但同时,模型的复杂度也在不断增加,并且看起来我们无法很快从模型中提炼出真正健壮的功能。

更麻烦的是尽管算法越来越复杂,我们却无法解决舍入运算所带来的细微差别。在1亿美元的交易中,确实没有人会在意几美分的去向,但是银行家是不会信任无法精确计算到美分的软件的。我们开始怀疑我们所遇到的难题可能是因为基本设计存在问题。

一、2 突破

在项目进行过程中,我们突然领悟到了问题的所在。我们在模型中把Facility的股份和Loan的股份绑定到一起,而这种方式并不适用于实际的业务。这一发现得到了广泛的认可。业务专家点头称是,并开始热情地给予帮助,我们迅速在白板上创建了一个新模型。虽然细节问题尚未确定,但是我们已经知道新模型的关键特征了:
Loan的股份和Facility的股份可以在互不影响的前提下独立发生改变。
有了这层认知,我们利用与下图类似的模型图走查了许多场景:



这张图表明Facility的总额是1亿美元,而借款者选择从中提取的第一笔Loan金额是5000万美元。3个放贷方按照各自原先承诺的Facility的股份来支付,这样5000万的Loan就被分配到了这3个放贷方头上。

随后,借款者又提取了另一笔3000万美元的货款(如图8-4所示),这样他的未偿Loan就达到了8000万美元,依然在Facility的1亿美元限额之内。这次,公司B决定不参与Loan,而由公司A来承担这部分额外的股份。各个放贷方在借款者提取贷款的过程中所支付的股份反映了它们的投资选择。当Loan的提取额不断增加时,Loan的股份份额就不再与Facility的股份成比例了。这种现象很普遍。

当借款者偿还Loan时,所偿还的金额会根据Loan的股份分配给各放贷方,而不是根据Facility的股份来划分。同样,利息支付也会按照Loan的股份进行分配。


图8-6 费用支付始终按照Facility的股份比例来进行分配

另一方面,当借款者为享有Facility权而支付费用时,这笔钱是按照Facility的股份划分的, 而不考虑放贷方是否借出了钱。Loan不会因费用支付而发生变化。甚至还有这种情况,放贷方单独交易费用股份,与利息股份等无关。

一、3、更深层模型

我们得到了两个深层理解。其一是意识到“投资”和“Loan投资”是“股份”这个常规基础概念的两种特例。信贷股份、货款股份、支付比例股份,这些都是股份,股份无处不在。任何可分配的价值都是股份。

经过几天忙碌的工作,我根据与专家讨论时所使用的语言以及我们一起研究的场景,初步搭建起了一个股份模型,如图8-7所示。
图8-8 使用Share Pie的Loan模型

Share Pie() percent pie

我同时也草绘了一个与股份模型搭配的新贷款模型。


图8-8 使用Share Pie的Loan模型

现在Facility股份和Loan股份不再由专用对象来表示了。它们都被分解成了更直观的Share Pie。这种泛化引入了“股份数学”的概念,极大地简化了所有交易中的股份计算,同时也使这些计算更富有表达力、更简洁且更易于组合。

但最重要的是,新模型删除了不恰当的约束,这使得我们的问题迎刃而解。Loan的Share因而无需与Facility 的Share成比例,同时新模型仍然保留着对总额、费用分配等的有效约束。我们可以直接调整Loan的Share Pie,因此新模型也不再需要Loan Adjustment和大量处理特殊情况的逻
辑了。

新模型中不再包含Loan Investment对象,我们此时才意识到“贷款投资”并不是一个银行业术语。事实上,业务专家早已多次告诉我们,他们不明白“贷款投资”是什么意思。但是他们还是尊重我们在软件方面的知识,并假定它对技术方面的设计是有所帮助的。而事实上,我们之所以创建它是因为没有完全理解领域。

这种看待领域的新方法使我们立即就可以毫不费力地处理之前遇到的所有场景,处理过程要比以往简单许多。业务专家认为我们的模型图非常合理,他们曾经指出我们之前的模型图对他们来说“技术性太强”。即使只是在白板上画出草图,我们也能看出新模型能够彻底解决长期困扰我们的舍入计算问题,我们可以不再使用复杂的舍入代码了。

一、4. 冷静决策

重构的原则是始终小步前进,始终保持系统正常运转。但是要按照这个新模型来重构则需要修改大量的支持代码,在重构的过程中,系统几乎无法正常运转。我们能够看出一些力所能及的微小改进,但这些改进无法让我们实现新的领域概念。我们也知道通过一系列小改动可以实现新模型,但是在这个过程中必然会导致程序的一部分功能无法正常工作。而且在当时,自动化测试还没有广泛应用于这种项目。我们一无所有,所以肯定会出现一些让我们始料不及的破坏。

此外,重构是需要花费精力去实现的。这时,我们与项目经理开了一次会,这次会议令我终生难忘。我们的项目经理是个睿智而勇敢的人。他问了我们许多问题:



他给我们开了绿灯,并告诉我们他会控制好局面。做出这种决定需要无比的勇气和信心,这使我一直对他钦佩不已。

我们全力以赴,在3个星期内完成了任务。这是个巨大的工程,但是却进展得异常顺利。

一、5、成果

项目需求不再有意外的、难以捉摸的改变了。舍入逻辑的实现虽然并不简单,却很稳定并且合理。我们交付了软件的第一个版本,第二个版本的开发思路也很清晰了。

在进行第二个版本的开发时,Share Pie成了整个程序的统一主题。技术人员和业务专家利用它来对系统进行讨论。市场人员使用它来向预期客户解释系统特性。这些预期客户和其他的客户都能立刻理解它,并且可以马上用它来讨论特性。由于它抓住了银团货款的核心问题,所以它真
正成为了UBIQUITOUS LANGUAGE的一部分。

二、 机遇

当突破带来更深层的模型时,通常会令人感到不安。与大部分重构相比,这种变化的回报更多,风险也更高。而且突破出现的时机可能很不合时宜。

尽管我们希望进展顺利,但往往事与愿违。过渡到真正的深层模型需要从根本上调整思路,并且对设计做大幅修改。在很多项目中,建模和设计工作最重要的进展都来自于突破。

三、 关注根本

不要试图去制造突破,那只会使项目陷入困境。通常,只有在实现了许多适度的重构后才有可能出现突破。在大部分时间里,我们都在进行微小的改进,而在这种连续的改进中模型深层含义也会逐渐显现。

要为突破做好准备,应专注于知识消化过程,同时也要逐渐建立健壮的UBIQUITOUS LANGUAGE。寻找那些重要的领域概念,并在模型中清晰地表达出来(参见第9章)。精化模型,使其更具柔性(参见第10章)。提炼模型(参见第15章)。利用这些更容易掌握的手段使模型变得
更清晰,这通常会带来突破。不要犹豫着不去做小的改进,这些改进即使脱离不开常规的概念框架,也可以逐渐加深我们对模型理解。不要因为好高骛远而使项目陷入困境。只要随时注意可能出现的机会就够了。

四、后记:越来越多的新理解

突破使我们走出了困境,但故事并没有就此结束。更深层次的模型为我们带来了意想不到的机会,它使应用程序的功能更加丰富,设计也更加清晰。

在Share Pie版本的程序发布几周之后,我们注意到在模型中还存在一个使设计变得复杂的地方。我们漏掉了一个重要的ENTITY,结果是本来应该由它承担的职责不得不由其他对象来完成。

具体来说就是提取货款、缴纳费用等业务是由一些重要的规则控制的,而所有这些逻辑都分散在Facility和Loan中的各种方法里了。这些设计问题在Share Pie突破出现之前几乎没有引起我们的注意,但是随着我们对领域的理解日渐清晰,它们也变得明显起来。现在我们开始注意到,那些经常在讨论中出现的术语(如“交易”,代表一次金融交易)并没有体现在模型中,反而隐含在了那些复杂的方法里。

经过与之前类似的过程(但所幸的是,我们有了更加充足的时间),我们对领域的理解又向前迈进了一步,并获得了一个更深层次的模型。这个新模型不但使所有隐含的概念显现了出来,如Transaction(事务),以及一个简化的Position(包括Facility和Loan的抽象类)。于是定义各种交易、交易规则、协商程序和审批流程就变得轻而易举了,而且实现这些概念的代码也相对来说变得更好理解了。
图8-9 几周之后的又一次模型突破。

通常,在经过一次真正的突破并获得了深层模型之后,所获得的新设计变得更加清晰简单,新的UBIQUITOUS LANGUAGE也会增进沟通,于是又促成了下一次建模突破。

当大部分项目由于规模和复杂度的累积而举步维艰时,我们的项目却正在加速前进。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 想在不削弱模型驱动设计能力的前提下对实现做出一些折中,需要重新组织基本元素。我们需要将模型与实现的各个细节一一联系...
    先生zeng阅读 426评论 0 0
  • 商务英语精选词汇 A abroad adv. 在国外,出国,广泛流传 absence n. 缺席,离开 absen...
    萝卜牛肉阅读 651评论 0 1
  • 第8章 召唤群魔 “嗷————”一声来自地狱的惨叫,嘶哑、绝望,是谁在濒死的边缘挣扎?或是一个小异形刚刚降生?还是...
    loxol阅读 284评论 0 1
  • 来源:实战财经 转自 优维金融空间 导读:包含银行系金融知识和基金证券类知识大全。 目录 第一部分:银行系金融知识...
    1e662a7de34a阅读 9,817评论 0 9
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,471评论 28 53