这几天刚开始学习DDD,看了几篇大神的文章,现在只是知道了几个名词,还没有详细的学习。结合自己的工作经历,说说自己的看法,请各位大神多多指点。
最开始用的比较多的是以数据库表建立模型驱动开发。后来发现这种开发方式有很大的弊端:项目开始的时候,对业务分析不够明确,就开始建立数据库表,之后根据建好的表,来设计怎么去实现功能。这就导致开发过程中,经常会有字段冗余,表结构混乱,分工不明确,相似代码太多等问题。接着就会在项目开始之前,有意识的分析业务逻辑,理清楚一个项目的功能模块,拆分不同模块,对每个模块再次详细分析,看都需要哪些实体,这些实体之间都有哪些联系,对实体都有哪些操作,等等。那个时候还没有接触到DDD,只是知道开发之前需要详细设计,分析不同对象的关系和业务过程。这样一两年之后,开发效率比之前忙着开发快了很多。这几天从公司一位大师那里听到了DDD的概念,就来学习一下。
DDD(Domain Driven Design)领域驱动设计,是一种业务设计思想。设计前期确认业务边界,划分功能模块,确认不同模块之间的关系和联系,以及交互方式,每个模块可以当做是一个领域来看。如果领域复杂,继续拆分成多个子域。后期确认业务实体的行为、属性,以及多个实体之间的联系。
驱动有两层含义:问题域驱动领域建模,领域建模驱动软件实现。(引自汤雪华大大的文章http://www.cnblogs.com/netfocus/archive/2011/01/17/1937779.html)
问题域驱动领域建模,主要是从功能模块、流程、和实现目标分析业务,不涉及具体的实体。业务分析好之后,实体一般是比较明确的,这个时候再编码实现,就会少走很多弯路。
领域的边界是服务,服务是对外的唯一入口,向外界反应业务领域实现的功能,和可以调用的接口。实体对象是业务领域内一个独立的具有一定自主能力的生命体,是业务领域内部的运行机制,不对外开放。体现领域的高内聚和不同领域直接的低耦合。
聚合:是一个域中的一个实体对象。
聚合根:可以和外部直接交互的实体。一个聚合根可以只有一个实体,也可以是包含多个实体属性的实体。
例如:一个订单对象,包含了 订单金额、收件人对象、订单商品明细 等属性信息,收件人对象包含了 姓名、联系电话、地址等,订单商品明细包含了多个商品信息。这个订单对象是和外部直接交互的对象,缺少了订单对象,收件人、订单商品明细 都没有实际意义。如果需要访问订单的收件人,则需要通过订单对象来访问。这个时候,这个订单对象就是一个聚合根,收件人、订单商品明细 则是聚合。
关于业务,包括了我们对一件事的处理过程和处理过程中涉及的实体对象,以及对象之间的关系。设计业务的过程,类似模拟人民处理事情的过程,也包括不同实体的关系,面向过程和关系的味道也比较重。
再说下充血模型和三层架构的贫血模型的对比吧,BLL 层的业务处理方法,相当于创建一个工厂里面,处理原材料或者半成品的处理部件,不同方法之间的调用,相当于传送带一样传递产品。DDD相当于创建了一个机器人,它包含了一些属性,和不同的功能,可以处理不同的任务。这就是贫血模型和充血模型的区别:贫血模型只是包含了一些属性,只能被动的被处理,传递;充血模型包含了属性和方法,可以主动的处理一些任务。
表达能力有限,还是举例来说吧。
一个业务场景:建造一个小区,首先是跟进地的大小、周围环境设计出可以建多少座楼,每座楼的占地面积,每层几户,每户多大,楼高,楼间距是多少,绿化面积、分布,等等,之后才是设计楼的外形,房间的户型,电梯位置等等具体的实体。
这个场景中,分析业务的流程,就是设计小区的过程,问题域是“如何建造一个小区”,服务是小区的几个大门,外界只有通过大门才能进入小区,一个聚合根是这个小区,它聚合了多个楼和停车场等实体,每座楼聚合了多个房间和电梯等。分析之后的实现,就是设计外形、户型,并建造的过程。
写的不好,也很少写东西,希望各位大神多多指点。