2.3.3 领域驱动的设计思想
前面谈到,软件的本质就是对真实世界的模拟。那么能不能将软件设计与真实世界对应起来,真实世界是什么样子,那么软件世界就怎么设计?如果是这样,那么在每次需求变更的时候,将变更还原到真实世界中,看看真实世界是什么样子的,根据真实世界进行变更。日后不论怎么变更,经过多少轮变更,都按照这样的方法进行设计,就不会迷失方向,设计质量就可以得到保证,这就是领域驱动设计(Domain-Driven Design,DDD)的思想。
那么,如何将真实世界与软件世界对应起来呢?这样的对应包括以下三个方面的内容:
1)真实世界有什么事物,软件世界就有什么对象;
2)真实世界中这些事物都有哪些行为,软件世界中这些对象就有哪些方法;
3)真实世界中这些事物间都有哪些关系,软件世界中这些对象间就有什么关联。
在领域驱动设计中,将以上三个对应先做成一个领域模型,然后通过这个领域模型指导程序设计;在每次需求变更时,先将需求还原到领域模型中分析,根据领域模型背后的真实世界进行变更,然后根据领域模型的变更指导软件的变更,设计质量就可以得到提高。
我们再次以前面电商网站的支付功能为例,来演练一下基于DDD的软件设计及其变更的过程。最初的原始需求是这样描述的,用户付款功能如下:
1)在用户下单以后,经过下单流程进入付款功能;
2)通过用户档案获得用户名称、地址等信息;
3)记录商品及其数量,并汇总付款金额;
4)保存订单;
5)远程调用支付接口进行支付。
采用领域驱动的方式,在拿到新需求以后先进行需求分析,设计领域模型。按照以上业务场景,可以分析出该场景中有“订单”,每个订单都对应一个用户。一个用户可以有多个用户地址,但每个订单只能有一个用户地址。此外,一个订单对应多个订单明细,每个订单明细对应一个商品,每个商品对应一个供应商。最后,可以对订单进行“下单”“付款”“查看订单状态”等操作。以此形成了如图2-9所示的领域模型。
有了这样的领域模型,就可以通过该模型进行如图2-10所示的程序设计了。
图2-9 付款功能的领域模型
通过领域模型的指导,将“订单”分为订单Service与值对象,将“用户”分为用户Service与值对象,将“商品”分为商品Service与值对象,以此类推,然后在此基础上实现各自的方法。