架构师如何应对复杂业务场景?领域建模的实战案例解析架构师如何应对复杂业务场景?领域建模的实战案例解析
为什么要领域建模?
软件的世界里没有银弹,是用事务脚本还是领域模型没有对错之分,关键看是否合适。实际上,CQRS就是对事务脚本和领域
模型两种模式的综合,因为对于Query和报表的场景,使用领域模型往往会把简单的事情弄复杂,此时完全可以用奥卡姆剃刀
把领域层剃掉,直接访问Infrastructure。我个人也是坚决反对过度设计的,因此对于简单业务场景,我强力建议还是使用事务
脚本,其优点是简单、直观、易上手。但对于复杂的业务场景,你再这么玩就不行了,因为一旦业务变得复杂,事务脚本就很
难应对,容易造成代码的“一锅粥”,系统的腐化速度和复杂性呈指数级上升。
目前比较有效的治理办法就是领域建模,因为领域模型是面向对象的,在封装业务逻辑的同时,提升了对象的内聚性和重用
性,因为使用了通用语言(Ubiquitous Language),使得隐藏的业务逻辑得到显性化表达,使得复杂性治理成为可能。talk is
cheap,直接上一个银行转账的例子,对事务脚本和领域模型进行比较,孰优孰劣一目了然。
银行转账事务脚本实现
在事务脚本的实现中,关于在两个账号之间转账的领域业务逻辑都被写在了MoneyTransferService的实现里面了,而Account
仅仅是getters和setters的数据结构,也就是我们说的贫血模式。
上面的代码大家看起来应该比较眼熟,因为目前大部分系统都是这么写的。需求评审完,工程师画几张UML图完成设计,就
开始向上面这样怼业务代码了,这样写基本不用太费脑,完全是面向过程的代码风格。有些同学可能会说,我这样写也可以实
现系统功能啊,还是那句话“just because you can, doesn't mean you should”。说句不好听的,正是有这么多“没有追求”、“不
求上进”的码农才造成了应用系统的混乱、败坏了应用开发的名声。这也是为什么很多应用开发工程师觉得工作没意思,技术
含量低,觉得整天就是写if-else的业务逻辑代码,系统又烂,工作繁琐、无聊、没有成长、没有成就感,所以转向去做中间件
啊,去写JDK啊,觉得那个NB。
实际上,应用开发一点都不简单也不无聊,业务的变化比底层Infrastructure的变化要多得多,解决的难度也丝毫不比写底层代
码容易,只是很多人选择了用无聊的方式去做。其实我们是有办法做的更优雅的,这种优雅的方式就是领域建模,唯有掌握了
这种优雅你才能实现从工程师向应用架构的转型。同样的业务逻辑,接下来就让我们看一下用DDD是怎么做的。
银行转账领域模型实现
如果用DDD的方式实现,Account实体除了账号属性之外,还包含了行为和业务逻辑,比如debit( )和credit( )方法。