代码改变世界

【讨论】“转账功能”引发的“谜团”

2011-06-22 20:30  bugfly  阅读(4880)  评论(54编辑  收藏  举报

今天拿出了一个憋在心中很久的问题来和领域驱动群的群友讨论,经过几小时讨论,总体上来说还是不能解决我心中的疑惑,所以直接拿出来和博友们来讨论一翻,希望以博客园大家的见识来为我释怀。为了让大家对所讨论的问题达成共识,就拿一个比较经典的ATM转账功能实现来展开讨论。如果我直接说大家都转过账,这未免太绝对了,但我相信在生活中,每一个人都听过这个词,废话少说直接进正题。

讨论的中心:如何从用例(功能)来精炼领域模型。

大家先不要急着回答我的问题,先对比以下落来的3位同学的对“转账功能”的具体实现。

1.甲君实现“转账”的代码



 评论:甲君这种实现方式,咋看上去并无问题,或许很多朋友也都是这样去实现转账功能的,包括我在内。

2.再看看乙君对“转账功能”的实现的。

评论:相信看到乙君的实现,各位肯定会喊当然是这种比较好啦,应该没人会说这种方式比第一种差吧,但反问各位这种做法为何好?好在哪里?为何能驱动出这个模型来?或许你们都会答,第二种明显维护的时候更省力什么的。。。我只能说从重构的角度来说,第一种有必要改进成第二种,但从功能实现的角度,抱歉,我无法单纯从转账这个用例精化出这种模型来。

3.看看丙君的“转账实现”

评论:相信有不少人看到丙君的实现第一反应是,这种比前两种貌似都要好,因为从代码量来说它是最少的,所以大家第一反应都会觉得这种更好,而我又反问你们,单纯从一个转账功能就能驱动出如何简洁的模型?究竟巧妙在哪里?每个看过三种实现方式的人都会觉得这种实现方式职责更加分离了,更容易维护了,更。。。就是说不出如何驱动出来的。

其实,我也觉得自己表达不清,所以题目打了两个字“谜团”,只能尽量去描述心中的疑惑:

 

已知条件:实现转账功能

问题结果:得出一个Account领域模型

结语:单从一个这么狭窄的已知条件去驱动出第二种方法的领域模型,各位你们凭什么得出这个结果?得出Redraw()和Deposit()方法?而第三种方法,又凭什么去把赋予Account对象一个转账行为,凭什么说转账是一个行为,请大家严谨地分析一下。

 

讨论结果:

经过各位的讨论,大致得出以下比较认同的第4种方案,见下图。

 

然而虽然说这种方案是大家比较认同的,但我本人觉得绿色框框的部分代码是为了替代转入(Deposit)和转出(WithDraw)功能而定义的行为,从业务概念理解上,很合理,也应该这么做,但始终有种换汤不换药的感。我会把最新的讨论结果更新上来,大家放心讨论和关注此文结果。