web服务程序设计探索(4)——数据总线-分层模型
2017-06-25 23:53
295 查看
一、数据总线-分层模型
为了使整个业务处理流程中,各层次功能界限划分更为清晰,降低各层次间的耦合性,参考计算机系统数据总线的方式,使数据流向各层。可以将数据总线想象成一根大的水管,整个流程像是“污水处理”过程:服务层(service层)接到最初的污水之后,将里面的一些物质初步整理出来(提取出参数,转化格式等),然后放入一个包(event-package)中,标注好这个包的ID以及它在service层的处理结果,然后扔回到水管中;包沿水管流到下一层(core业务逻辑层)进行处理,core业务逻辑层拿到service层处理后的数据,根据ID对应的业务规则进行处理,将处理结果塞回到包中,再扔回到水管;包流到db数据修改层,这一层会检查这个包是不是自己要处理的包,如果不是原样扔回到水管,如果是,则进行处理,并将处理结果塞回到包中,把包扔回到水管…最后包流回到service层,这层按照具体的协议,从包中取出数据,处理后返回给客户端。
整个过程中,每一层的输入都包含一个event-package流入的接口(还有自身所需的一些其他参数);返回一个更新之后的event-package;各层之间没有直接的函数耦合。
二、数据包结构说明
event-package的数据结构如下:{:event-id :事件ID :result :success/:failed ;;事件处理结果 :reason nil ;;导致事件处理结果(失败)的原因 :params {:param1 .. :param2};; 事件参数 :db {};;db层所需要的数据 :resp {};;resp层所需要的数据 }
对于每个业务请求,流经每一层时,每层的处理结果都会反映在:result字段中,如果在该层处理失败,则会将:result改为:failed,并且在:reason中说明原因(如:invalid-username);core业务逻辑处理层,依旧是系统的核心层,它决定这整个业务处理的核心逻辑,其处理后,会将数据放入:resp和:db(如果需要修改数据库);:db层和:resp层就可以从这些字段拿到自己处理时所需要的数据;
二、层次说明
service层
该层为服务层,主要提供网络服务,如http服务;这层会对客户端过来的消息进行解析,如从url或body中取出参数,对参数的数据格式进行转换,对请求进行路由等;提取出来的参数,放在event-package的:params字段中;core业务逻辑处理层
该层依旧为系统的核心层,根据每个请求对应的业务处理规则,对业务进行处理,处理后的数据。该层是一个纯函数层,它的数据来源有两个:一个event-package里面的params,一个是db-data;它的输出是一个更新后的event-package:如果请求不满足业务规则,将设:result 为:failed,并在:reason中注明原因;如果满足业务规则,则将处理之后的数据放到:db和:resp中,供下层使用。db数据修改层
该层为副作用层,也就是对数据进行修改,它从db中获取自己处理过程所需要的数据。该层并不是一个脱离业务处理流程的、单纯执行transaction的层,它需要理解自己需要对那些event-id进行处理,它需要知道自己在每个业务流程中要承担的角色。同样它会将处理结果反映到event-package中。resp-msg层
该层主要根据上面层次的处理结果,生成返回给客户端消息内容,但这个消息并不是最终消息,只是将上面层次的处理结果“翻译”成消息协议所规定的消息。比如如果流入的event-package为:{:event-id :add-user :result :failed :reason :invalid-username :db nil :resp nil}
resp会将其翻译为:
{:result :failed :data {:msg "非法用户名“ :reason :invalid-username}}
该数据被传回到service层,service层会为每个reason指定相应的http状态码,然后加上:data数据,返回给客户端。
三、优点
低耦合性
每一层都是相互独立的,甚至是可拆装的。比如拿掉了db层,整个程序也能正常走通。层与层之间的耦合是数据耦合,也就是说,只要该层能够理解这个数据结构,就可以通过拿到的数据进行处理。开发节奏好、效率高
每层都是独立的,因而可以独立开发。只要定义好接口的数据结构,就可以并行开发或者先行开发某一层;比如可以先开发最核心的core业务逻辑处理层,再开发resp,这样就能将核心业务通过单元测试用例跑起来(因为这两层是纯函数的),并且通过测试用以保证核心逻辑的正确性和稳定性;逻辑开发完成,就可以实现service层,这样可以迅速和客户端实现联调;最后再开发db层,使用真实的数据读写;先写纯函数层、再写副作用层,尽力将开发时间停留在纯函数的编写,这是一个好的开发节奏。纯函数具有易测试的特点,因此适合于“测试驱动开发”的模式,能够快速开发出正确、稳定的业务逻辑。
易于维护
因为层次间相互独立,每次基本上都可以使用自己的特有的技术,比如可能需要改变的db层:开始使用的是mysql的数据库进行存取,而现在需要使用datomic数据库。此时可以很轻易的进行替换,因为event-package中有db层所需要的所有数据,并且这些数据都是业务数据,并不是根据db层所使用的技术定的。再比如service层,如果不想使用http提供网络服务,而是使用socket,那么也只需要更换service层即可,只是接受客户端参数的处理和回复消息处理因技术不同而发生改变,不会影响其他层次。易于扩展
比如要加入业务日志记录,可以再加一个log层,而不需要在其他层次中插入各种log/error,log/info语句。这有点像spring的面向切面编程;再比如,如果要将数据发送到某个远程服务进行处理,可以选择修改db层(封装了各种数据库处理,远程调用等操作),也可以选择再加一层。四、缺点
一个大的event-package数据结构,感觉有点大。每个请求处理,都会需要修改event-package,而修改event-package像是业务之外的“额外操作”。相关文章推荐
- web服务程序设计探索(2)——插件模型
- web服务程序设计探索(3)——中间件模型
- 使用 WCF Web HTTP 编程模型创建返回任意数据的服务
- 数据和服务 – 通向企业服务总线(ESB)之路
- [Sharepoint2007对象模型]第二回:Web应用程序服务(SPWebService)
- Java Web 服务,第 2 部分: 深度探索 Axis2:AXIOM
- 如何在 Web 服务中使用 Service Data Objects 2.1 的动态数据 API
- 老鼠Atlas之旅(四):提交、返回复杂数据类型给web 服务
- [Sharepoint2007对象模型]第二回:Web应用程序服务(SPWebService)
- Winform+WebService分层模型
- Web 应用中用户录入数据错误检查在分层设计中的定位
- Rational Edge: SOA 的未来 —— 具备 Web 2.0 能力的基于服务的交付模型
- Web 服务全球化模型
- 在 Web 服务领域公开和使用数据 【转载】
- 使用 XSLT、KML 和 Google Maps API 在地图上覆盖数据,第 1 部分:利用 Google Geocoder Web 服务
- Web 服务所支持的数据类型
- 通过web服务传递复杂类型数据的一些尝试和心得(欢迎讨论)
- 解读Windows 2000/XP分层驱动模型(http://webcrazy.yeah.net)
- web开发中的分层原则和各层之间的数据传递问题
- WEB开发中的分层原则和各层之间的数据传递问题