web服务程序设计探索(4)——数据总线-分层模型
来源:互联网 发布:电火花成型加工编程 编辑:程序博客网 时间:2024/06/07 12:48
一、数据总线-分层模型
为了使整个业务处理流程中,各层次功能界限划分更为清晰,降低各层次间的耦合性,参考计算机系统数据总线的方式,使数据流向各层。可以将数据总线想象成一根大的水管,整个流程像是“污水处理”过程:服务层(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服务程序设计探索(4)——数据总线-分层模型
- web服务程序设计探索(2)——插件模型
- web服务程序设计探索(3)——中间件模型
- web服务程序设计探索(1)——俄罗斯套娃模型
- 分层分离的总线驱动模型分析
- 驱动分层/分离,总线驱动设备模型
- 网络分层——OSI模型
- 计算机设计思想 —— 分层模型
- 6410之驱动程序的分层分离,总线设备驱动模型
- 驱动程序分层分离概念_总线驱动设备模型
- 嵌入式linux之分离分层概念,总线驱动设备模型
- 分层模式下的Lazy Load ——探索Domain Model系列(下)
- 总线设备驱动模型——总线篇
- Linux设备驱动模型4——平台总线实践
- Web 服务全球化模型
- ROS探索(3)——SmartCar模型搭建
- 深度探索c++对象模型——读书笔记(一)
- 深度探索c++对象模型——读书笔记(二)
- Java 多线程之内置锁与显示锁
- powershell:Invoke-WebRequest : 请求被中止: 未能创建 SSL/TLS 安全通道
- Java单例设计模式
- C程序设计进阶week6(指针3)
- PMP模拟试题与解析(九)
- web服务程序设计探索(4)——数据总线-分层模型
- hdoj 2037
- LeetCode算法搜索
- 记账软件_强迫证处女座的福音_功能不是最强大,绝对最实用的记账软件
- 使用Windows远程桌面(mstsc)通过RDP协议访问Ubuntu/Debian服务器 时间:2015-05-16来源:linux网站 作者:wangxiaoyu 觉得通过Windows原生的远程
- hdoj 2051
- Scala基础—集合函数式编程示例(占位符的使用示例)
- redis scan 命令遇到的坑总结
- CPU卡COS系统文件结构详解