领域驱动设计(Domain Driven Design,DDD)是2004年由Eric Evans提出的:任何软件开发都不应只关注技术,业务领域才是软件开发更应关注的重点。去年这位老兄在DDD欧洲的峰会上大谈伪代码,再次强调了需要让业务领域的专家介入并指导应用间的关联关系,通过伪代码论证其技术可行性。
领域驱动设计作为服务设计的顶层视角,它的业务属性还是要强过技术属性,尤其是当为某一业务域开发技术模型以为今后的软件提供开发基线的时候。首先我们来说说这个“顶层视角”,如果站在软件开发的视角,应用的底层是打包好的java/.net的程序文件,其上有调用对象和调用方式,再往上是类以及指导类封装的面向对象协议(Object Oriented Principle,OOP),有时软件还会有范式的抽象层,再往上就是模块、分层和整个项目。
当然任何一个大型企业会有多个业务域,每个业务域甚至会包含业务分域和业务子域来规划上述一个个软件服务。这也就是上一段提到的顶层视角,用通用的话术即:顶层设计(DDD)是服务规划的战略视角,软件开发是服务规划的战术视角。
史蒂夫乔布斯有句名言:“客户并没有义务知道自己想要什么”(It's not customer's job to know what they want),企业需要更多站在对自身行业的深入理解的基础上帮客户规划产品功能和体验。
从战略规划的角度,服务设计主要关注上下文地图(即各个业务子域间的联系),有界上下文(业务子域内的服务设计)和通用语言(Evans先生本人非常关注的业务“开发语言”)。
为什么通用语言很重要,是因为顶层设计是由业务领域专家驱动的。好比盖一栋房子,软件专家可能会知道通用的平房该怎么设计,或者说标准的地基、立面、封顶的标准结构是怎样的。但是房子是有很多种类的,而不同种类的房子有不同的功用,就需要从对外功能上规划每一个功能点的实现。比如说一个农场,软件工程师亟需调研在这一领域的规划专家,农场该有怎样的功能,甚至可以借助一些同业案例规划各个上下文子域。
随着对领域专家的访谈或同业案例的研究,我们了解了农场需要有农舍、工棚、马厩、谷仓、菜园、大门和篱笆组成,这就相当于是主领域下的各个功能子域(或有界上下文,bounded context),然后每个功能子域有各自的业务目标,比如工棚用来帮牛产奶,谷仓用来打谷子存放粮食,农舍用来给农场主休息等等。
那具体落到设计上,比如农舍就要具备餐厅、起居室、车库等空间以满足主人不同的生活需求。而类似餐厅、起居室这样的描述就是通用语言,而通用语言是不能跨越有界上下文的,即农舍里的起居室和马厩里的起居室可能表达的完全不是一个意思。
通用语言其实泛指某一种可以跨越技术和业务的交流方式,可以在领域专家、业务分析师、开发人员间无损传递信息。片头提到的伪代码就是一种通用语言。
技术的语言业务不胜理解,反过来业务的语言技术也会云里雾里,例如如果领域专家说“西北翼的房间带吊顶和一进露台,悬挑板高20厘米”,施工工人大概也会不明就里。但是既然是顶层设计,领域专家或者业务分析师不用太关注服务的具体实现方法,画好农舍、工棚、马厩等的平面图就差不多大功告成了。
当然农场的例子还只是在平面图这一个维度进行子域的划分,落到企业内部不同的子域会有不同的关注点,单就客户主题来说,销售会关注客户的社交网络、喜好和需求;售后会关注客户的消息历史、投诉建议等等;财务会关注客户的付款方式;仓库会关注客户的地址和状态。可见在不同子域聊到客户,其实讲的是不一样的东西。即便这些东西在一个主数据管理系统中,也需要分字段发布到不同的子域中。
领域驱动设计的模型也就是将上下文地图、有界上下文和通用语言有机的结合起来,在地图中明确表示各有界上下文的逻辑关系,在各有界上下文之内用通用语言描述建设规范和目标。
很多场合我们一直会说程序员改变了这个世界,本座想强调的是不是程序员的技术水平,而是他们对业务的理解改变了这个世界!