对于跨系统和模块间的SOA服务识别和分析我前面文章谈的比较多,这块的SOA服务重点是实现跨系统和模块的业务交互和协同,而对于领域服务而言则更加关心的是对于单个系统或模块,其应该如何抽象领域对象并将其能力以粗粒度服务方式保留给应用层用。在领域建模中的整体思路中,我们做两个层面的理解,其一是领域模型层重点是隔离传统的数据表并抽象为领域对象;而对于领域服务层重点是则将应用层和领域模型层解耦,模型层提供的能力是以领域服务的方式暴露到应用层使用的。
对于最贫血的领域服务层,就是一个DAL层封装的服务化,即只提供数据库表CRUD能力的服务化,在这种情况下基本满足所有的业务处理和应用需求,但是领域服务层没有任何领域逻辑,也没有领域对象的转换。而我们这种需要的领域服务主要包括三个方面的内容,一个是领域对象识别,然后将领域对象的类似CRUD操作暴露为服务;其二是对于核心的业务规则的识别,将业务规则识别为业务服务;其三是组合服务,根据业务场景需要将几个原子服务组合为一个更大的服务。
领域对象我前面已经谈到过,领域对象是具有完整相同的生命周期的对象,领域对象中的各个子对象不能脱离主对象独立存在,如我们经常说的订单,合同,供应商都是领域对象;但是这些领域对象在后台往往存在多张一对多的数据表,如订单至少包括了订单头和订购明细信息等。在领域对象识别中必须要首先识别核心的实体对象,在根据实体对象的属性需求来识别值对象,领域对象识别清楚了再根据业务场景的需求考虑领域对象的能力暴露。
领域对象中有一个核心就是将数据库表对象转化为领域对象,并将领域对象的能力暴露为粗粒度的服务,即数据库的CRUD能力转换为了对象的生命周期操作能力。但是在这种分析模式下容易遗漏业务规则转换为业务服务部分的能力需求,这类业务服务往往需要在对象关联依赖和真实业务场景和用例活动中才能够识别。举例来说供应商领域对象开始只识别了供应商的增删改查的对象处理能力;但是在我们做采购订单和合同的时候,有一个业务规则是需要校验供应商是否有效?在这种场景下我们需要将这种独立可复用的业务规则转化为业务服务,这种业务服务相当多,也可复用,属于我们经常说的粗粒度服务范畴。还有一类是组合服务,跟业务流程中的子流程或活动相挂钩,如银行转账,资产调拨,供应商合并,单据提交(单据保存+流程启动)等,都是典型的组合服务,往往需要调用多个原子服务或原子API操作才能够完成。这种组合服务能力可以进一步在领域服务层进行封装。
在引入了领域对象层和领域服务层后,需要对传统的分层架构进行调整,首先是引入领域对象,对原有的数据库表对象进行第一层抽象,数据接口转换为对象接口;其次是对原有的展现层和逻辑层进行解耦,引入领域服务层,在领域服务层需要承载业务逻辑,但是又不是完全承载;初步思考的是原有的业务逻辑层的内容有1/3左右划分到应用层;而2/3左右能够下沉到领域服务层。领域服务层贫血很多时候可以追溯到原有分层架构中本身的业务逻辑层就贫血,业务逻辑层逻辑都放到应用层和数据库存储过程中,自然转换到领域建模中也存在贫血的问题。
领域对象服务中的领域对象本身就是多个数据表的汇聚,所有对象服务可以解决对象级的事务问题,如订单保存中头和明细的操作严格控制在一个事务里面。但是对于领域服务层的组合服务仍可能存在分布式事务的问题,在这里还是建议基于BASE模式思路进行操作。还有一个方式就是对于组合服务而言,不用直接对原子服务进行组合,而是对原子服务下层的对象级操作API进行组合,这样即方便启用数据库层或逻辑层的事务进行事务控制。
青春就应该这样绽放 游戏测试:三国时期谁是你最好的兄弟!! 你不得不信的星座秘密