说起企业开发软件架构一般分为事务脚本和领域驱动,在.net阵营中比较流行ActiveRecord和表模块架构,这两种和事务脚本本质是一样的,都是面向数据库开发。企业级应用日益复杂,面向数据库开发在前期开发会比较快。但就像是没有打地基的楼房一样不可靠,.net提供了一种把数据库表模型转换为领域模型的方法,这个比较搞笑,表模型是是数据模型是平面的,2维的,领域模型是业务模型,3维的,你可以把领域模型转为数据模型,但是无法倒转。软件解决的是领域的业务逻辑问题,而不是解决业务数据该怎么存储。

    架构的本质就是分离关注点,要把业务关注点和技术关注点分开考虑。关系数据库只是持久化数据的一种技术,面向关系表开发就是把技术和业务耦合在一起,基于关系表开发是考虑平面数据和数据关系和数据库相关技术,严重腐蚀了业务本身,开发出的系统很难表达真实的业务,领域模型则是体现业务的本质,分离出业务关注点,技术关注点是基于业务关注点的。在面向数据库的开发方式中,业务逻辑都写在应用层的Service中,对于每个用例,每个业务需求都一行一行的在Service中实现,这样每个Service就是平面的信息孤岛,大量代码重复,随着时间的推移维护成本上升,生产力下降,维护人员根本不愿意修改代码,项目或产品风险越来越大。为了避免这个问题,就要做好软件架构既分离关注点。分离关注点最常用就是分层,把系统分为几层,每一层都有自己的关注点,而领域层是核心关注点,是价值所在。其他层都是为领域层做支撑用的。领域模型就是业务本身,需求的变化直接导致模型变化,面对模型的驱动可以把业务的本质了然于胸,从容面对需求变化。领域模型是怎么得到的?我们在接触领域的一开始,只能在脑中抓到领域中的一些基本概念,这时候建立的是基本概念模型,是幼稚的,随着迭代对业务的不断了解,开始能抓中众多需求的本质,把模型抽象,把重要的业务规则从隐式的转化为显式的,去掉华而不实的模型和关联等等,不断的精炼模型,这样从浅模型得到深层模型。

   领域层的业务逻辑经常会和应用层的技术弄混,如何分辨2者。例如论坛有加精置顶等很明显就是业务逻辑,而文章管理中文章增删改就不是业务逻辑,只是持久化的技术实现。表示层、应用层、基础设施层都有很多具体框架和方案,唯独领域层没有框架、这就说明其他层都是横切,只有领域层垂直的,是个性的,是最需要我们关注的。领域模型就是关注领域业务的最好方法。领域模型分为实体、值对象、服务,工厂和仓储控制其生命周期。实体容易理解,就是要追踪的有唯一标识的并且可以映射到关系数据表。值对象一开始会给习惯于面向数据库的人造成困惑,举个例子:实体经常会有状态,一般会用一个数字或字符基本类型来区分状态,但是如果状态复杂,有多个属性,还要有职责,像是状态转换这种,就是用自定义的对象来代表状态,这个状态对象就是值对象。从设计模式的角度来看就是状态模式。状态、类型、有效期等等这种描述性的属性最可能是值对象。服务和应用层的服务是两回事,服务用来调用实体和其他服务的,经常是动作,例如银行转账涉及到2个账户实体,转账收费。电信计费涉及到账户实体,计费策略等等这些就是领域服务。

   通常领域层的代码只占整个系统中很少的一部分,但是价值却占很大比例。在实现领域代码时候,应该由水平最高的工程师来实现,对这部分代码进行精心测试,因为领域模型就是POJO的,不依赖任何框架,所以比其他层的代码都容易测试。在代码实现的时候,是对业务细节也是更深的理解过程,这时候也可能对业务模型有新的认识,所以在代码实现的过程中领域模型也在深化。领域模型实现不应依赖任何技术,不依赖其它层,不会因为你是否用了spring或者ejb、hibernate而对领域模型做出改变,领域模型的改变的因素只能是业务,而不是技术。在领域模型驱动的开发过程中,要随时警惕其他层对领域层的腐蚀。领域驱动就是用领域业务来推动整个工程,需求之后就是建立领域模型,确定领域模型的属性、职责,关系。用最好的资源来实现和测试领域层代码。领域模型就是业务就是文档。在领域模型面前彻底忘掉数据库表,专心面对业务。领域驱动不是一条容易走的路,但是你走熟练了,这条路会带给你不断的惊喜。