DDD的终极大招——By Experience

以DDD思想和微服务架构为代表的新的架构时代正在逐步形成,不同方法和工具的涌现让人激动不已,同时这个过程也让人感觉到些许的不安,因为没有一套方法和一套架构能够打遍天下,我们能明确告诉所有组织和团队的,也只是架构设计上应该“响应变化胜过遵循计划”!具体到采用哪一种架构设计思想和方法,仿佛都需要增加一个定语“这取决于……”。

以去年的“明星”方法Event Storming(ES)为例,今年已经开始被不少人所批判。内行已经开始调侃这就是“糊墙”(不明就里的同学可以感受下图中的ES现场)。而实际上ES创始人Alberto是一位很低调的实践者,仍然在不停地磨练着他发明的这套方法。一年里我也接到了无数类似“我们是xxx领域,有xxx系统,ES感觉好像用不上?”的问题。我的答案往往是:“没事儿,你们先试试,找到具体困难点,咱们再看为啥不好用。”

(一个ES现场,“糊”满各色纸贴的建模过程。)

我相信得到这个答案的部分团队可能真的去尝试了ES,但鲜有人再将他们遇到的具体困难反馈给我 —— 也许ES实践本身就是困难,而不是他们要解决的业务问题。但我的出发点却并非推广ES,而是让团队能够获取“经验”!这点上还是小有成就的,去年我可能还是中国区“糊墙”最多的人,今年很多人都远胜过我了。

不管是在DDD原著,还是后续不少专家的书籍中,都明示或暗示架构设计最后的终极大招还是By Experience ——靠经验吃饭。从战略角度的subdomain(子问题域的划分)到战术建模层面Entity、VO的选择,最终的决策很可能不是完全“理性”,经验这个“感性”的东西发挥着很大的作用。

对于一个顾问和教练来说这是绝望的答案,因为我们每次面对的是希望学习,但没有经验的团队,“靠经验吃饭”等于告诉团队这东西没套路、靠感悟。这就迫使我们转换视角,从教大家DDD方法,转换到帮助大家获取DDD经验。下面就让我们来看看怎么有效解决DDD经验获取这个问题。

问题、问题、问题

DDD作为一种架构方法,最大的突破应该说是非常明确地区分出了问题域和解决方案域。而认知问题这件事情绝对不是技术人员擅长的,从我们学习编程起,我们就被如设计模式(Design Pattern)这样的解决方案所包围。想当年我自己最得意的事情也是refactor to pattern,也是把解决方案当成了“终极问题”来追求。

这往往是一个痛苦的蜕变,需要有人在你身边不停念叨“你说的问题是什么?”。你必须要做到心平气和,即使你认为对方是故意挑衅,有时候挑战更能促进思考上的突破。比如我经历过下面的一段经典对话:

甲:我认为这个子问题域是客户账户管理的问题。

乙:我觉得你已经在说解决方案了。

甲:客户账户管理是问题,我并没有提怎么管理啊!

乙:谁说一定要管理客户?!我还是觉得你说的是解决方案!

甲:(受不了你了… … )不管理客户我们做这个系统干啥?

乙:我就是这个意思啊,为啥要做这个系统?我们解决了什么业务问题?

甲:这么说的话那把业务找过来,看他们怎么说。

乙:行,反正DDD里说领域专家很重要,业务来了再讨论。

某种意义上这两位技术人员的争论是卓有成效的,最终的发现是业务问题其实并不清楚,远没有达到可以进入解决方案建模讨论的时候。

跨领域合作

当然上面的对话还有另外一个有意思的核心观点,即由于问题和解决方案在整个建模过程中是不停深入和迭代的,所以我们必须鼓励,甚至要求从业务到技术跨领域的人员参与和协作。

这点是我为什么仍然认为ES是一个好方法的基础,当然与我相对的观点是,如果有了真正的领域专家,搞那么复杂的协作有必要吗?ES通过对事件(event)的利用,提供了一套业务和技术能够共同理解的协作机制。在我的辅导过程中,很容易让两边的同学都理解如何上手。

(ES的运作机制,很有效的利用了Domain Event;注意这里的event是业务事件,而非技术实现。我的同事伍斌在自己的简书中详细记录ES的采用过程,欢迎大家查阅。)

当然如果真有经验丰富的领域专家,确实事情就简单了很多。业务问题的分解首先就变得非常流畅,ES的功效也就不那么明显了。然而我个人始终认为“团队共同的学习 胜于 建模本身的正确性”,即使专家也不能完全预见未来,所以团队能够有机会通过某种手段学习专家的知识,也是很有价值的一件事情。

从需求到代码

DDD最初吸引我的地方是能够从问题分析一直拉通到代码实现,这有别于很多其它的架构方法,总是在某个链条上产生脱节。所以DDD的经验获取也需要尝试让团队端到端的拉通体验。

然而事实上很多团队仍然在践行着脱节的实践,比如建模后产生的Entity仍然用传统的数据和行为分离的实现方式。这样的实践方式显然是有悖于DDD的初衷,如果不能让业务和系统模型实现绑定关系,很快就会走上各说各话的老路上去。

实践端到端也有一定的技巧,首先应该明确分层架构的原则和规范,比如是否有Application Service存在的必要,Interface的调用规则等等。在此基础上,需要明确守护Domain Model的纪律,时刻保证代码和建模的一致性。最后需要建立分层的测试机制,特别是对Domain层逻辑的守护。

和前两点相比,这真是一个需要全队刻意练习的过程,坚持信念是团队走过开始阵痛期的必要条件。

刻意“失败”

之前在辅导团队的时候,一个常见问题就是团队纠结于一个业务概念建模采用Entity,还是VO。经常会听到团队说:“从现在的需求来看,VO应该是完全够用了,但很显然接下来我们马上就需要有业务状态的变化,很可能VO就没法玩了。”

针对这样的问题,我往往会刻意引导团队从简单的VO建模入手,先不要考虑“未来”的需求,即使有时候这些需求已经相当明确。这样的刻意行为显然会造成团队在接下来的时间里改变模型,VO可能会被重新建模成Entity。短时间有可能是痛苦的,很多技术人员也会跳起来说,你这是“站着说话不腰疼”。

但DDD的核心就在于持续的演进,演进就意味着模型和实现的改变。这样的改变和上面我们刻意安排的“失败”其实是一致的。当我们通过这样的刻意练习获取了演进的经验后,业务和架构未来的变化对我们来说就真的可以by experience了。

写在最后

开篇我就提到了一个新的架构时代正在浮现,不同于之前的架构方法,没有一个组织和企业会在这个时代告诉你这就是做架构的正确方式。数字化时代的系统和应用在不停进化着,速度越来越快,想要找到进化过程中正确的元方法是非常困难的。

DDD的终极大招By Experience某种意义上是在持续探索,并要求大家接受在这个探索过程中的不确定性 —— 你的设计有可能在未来被证明是错误的。这可能是未来架构设计最大的挑战,我们必须能够让架构持续演进。

《演进式架构》已于今年问世,带给我们很多这些方面的思考,类比人类社会的演进,数字化世界的构建和发展应该有很多地方可以借鉴和学习。当然就这个问题而言,不管是DDD,还是Microservices,都只是我们探索架构演进的开始,我们还有很多的Experience需要获取!


文/ThoughtWorks顾宇
更多精彩洞见,请关注微信公众号:思特沃克

猜你喜欢

转载自blog.csdn.net/toafu/article/details/83537783