在ddd设计中我们经常会提到服务层,服务层是什么?职责是什么?有什么好处?。
先看简单的层次图(注:这里并没有考虑其他多余的领域逻辑数据层存储,或者UOW这些细节)
我的理解是服务层是处于我的应用程序业务层和表现层之间的应用程序边界,边界可能是很薄的一层类设计或者是分布式服务网络跃点。它是一个与技术无关的名词。由表现层直接调用,契约,执行命令(修改状态(CUD))或者是查询返回dto(数据迁移对象)(cms,命令-查询分离)。他对业务逻辑层接口很清楚,组织业务逻辑 微服务形成宏服务,适配表现层。
这里谈到宏服务和微服务,宏服务有一些列粗粒度的服务组成。用户的一次操作usecase,比如电子商务下单,CreateOrder就是一个宏服务,而不是下单中的细粒度的商品库存检查,订单合法性等。而与之对应的微服务(有时也叫应用程序服务),则表现为问题领域逻辑细节,就如上面的库存检查和合法性检查这些细粒度的服务。宏服务是由一个或者多个微服务组成,有时我们的usecase逻辑很简单服务层仅由单一微服务组成,变现为很简单的几句微服务调用。
服务层的职责:
1:在面软件开发不管是结构化编程(sp)还是面向对象编程(oop)我们一直都强调高内聚低耦合,分离关注点(soc)。服务层处于应用程序和业务层之间,应用边界,使得两次直接解耦,利用第三个对象破坏两对象直接的依赖,并转化适配领域对象(do)和试图对象(vo)的差异。
2:服务层隐藏了业务逻辑层的细节,其内部需要组织业务微服务,提供更宏观,面向表现层的服务逻辑,利用契约接口暴露,包装。系统所有的交互都是从表现层进入。
目前流行SOA架构,提供了一种分布式服务架构,以服务为关注点,提高服务和业务逻辑的重用,但是这里说的服务并不是特定的技术wcf或者webservice,服务同时候可能是一次规定契约的一些列粗粒度组织的类组成。但是利用SOA或者MTS建立服务会让我们的服务得到跟多的附加优势,例如安全,事物,日志,扩展性的提升。
服务层带来的优势:如上所述服务层为表现层提供的同一的接口契约和入口。让我们的业务层可以关注与实现问题领域逻辑,问题领域实际需求。组织微服务避免太多的细粒度服务的调用充斥在我们的项目表现层和问题领域中,过多的交互。如果采用soa等服务领域可以让我们的应用程序轻易的跨过应用程序边界和网络跃点。但是需要付出一点的性能代价。
数据迁移对象(dto)就是携带数据穿过应用程序边界的对象,减少数据的交互次数,常常我们将其作为值对象,只是一组简单的get,set属性组成,不存在行为操作,仅仅为数据的载体。在领域设计中dto是一个很重要的模式,不是我们所有的领域对象都能轻松的到达表现层,仅仅表现层和领域层部署在同一物理位置。如果需要穿过网络跃点或者进程边界,因为领域对象使我们的业务的核心存在很多的自然世界的关系,依赖,甚至可能存在循环依赖比如电商用户和订单,用户用户一组订单的集合,而每个订单都指向一个特定的用户,我们就必须破换掉这种循环依赖,才可能使其可序列化,穿过跃点。其次我们的领域对象往往都是一堆领域富对象,存在大量数据,很多时候我们的场景并不需要全部的数据信息。有了dto的存在就能很好的解决这些问题,是的我们的项目变得simple(keep it simple,Stupid。 KISS原则)。
但是与此同时dto存在会为我们带来一些额外的复杂度,我们必须有一层do到dto的映射适配层。
理论上完美的设计我们需要为每一个应用定义一个dto,但是在一个复杂的系统中我们可能存在很多的领域对象,加入500个do,每个do一般都会存在多个dto,这将一个增加一个庞大的集合和mapping逻辑,对于维护也存在不小的挑战。在软件领域存在一句话就是bug的数量随着代码量增加,代码量增加需要测试点也随着增加。除非我们必须跨越应用程序网络跃点边界,我觉得否则我们也可以存在一些简单do的直接使用。根据世界项目,情形由我们的架构师决定。
作者:破 狼
出处:http://www.cnblogs.com/whitewolf/
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-博客园--破狼和51CTO--破狼。