“六神”——技术提升开发效率的一个方案

这个方案并非我在系统设计方面的最先一次尝试。但它在提升开发效率方面,是效果最为显著的一个方案。java

简介git

“六神”框架提供了一套简单而通用的、从Web层到数据库操做(增长单个数据、删除单个数据、修改单个数据、查询单个数据、查分页列表、查不分页列表,六个操做,所以名为“六神”)的基础组件。而且,它为复杂的数据库操做留下了扩展点。github

在当时的技术背景下,这套框架使用Struts2.0+Spring+myBatis来实现。可是它的设计思路是能够适用于其它技术的。数据库

在应用了这套框架以后,咱们那个系统在一个月时间上线14个功能模块,效率提高了近三倍。json


背景app

当时咱们接下的项目是一个近似于OA系统的稽核系统。这个系统的主要功能有两类:一是各类数据、信息的增删改查;一是各类审批流程。审批流程的设计按下不表,“六神”就是为增删改查功能而开发的。框架


思路异步

在完成了几个增删改查的页面功能以后,我发现它们很是类似。ide

功能上,它们都是打开页面时查询一个分页列表;而后新建一条数据;按id查询出一条数据,并展现在弹出窗口上;弹出窗口上能够修改某些字段的值;某些页面上还须要提供删除数据的功能;部分配置数据、基础数据须要提供查询不分页列表的功能。微服务

流程上,则几乎都是页面提交一个http请求,Struts 2.0的action从中解析出参数;service层调用对应的mapper;myBatis生成并执行SQL,将操做结果返回给service;service直接将参数交还action;action将返回值转为json字符串写入http响应中。

而它们之间的差别性,基本是入参和出参的封装类型、以及数据库操做的SQL上。


流程图

上述六个操做,均可以用下面这张流程图来描述。而不一样的操做、不一样的业务需求之间,基本上只有object以及SQL有所不一样。

wKioL1jT6RawvkPZAACPsveObSY556.png-wh_50

类图

wKiom1jT6Rfwj0n5AAHb9s5ndHw527.png-wh_50

“六神”的主要类图中,以接口定义居多。其中的BasicDbAction和BasicDbMapper,是当时Struts2.0和MyBatis框架中的两个实现类。


Service层上分出来了六个接口。这是为了保持接口的隔离性。可是默认类实现了所有接口,只是全部方法都直接抛出异常。实际上就只是提供了一个Adapter而已。

Dao层一样有六个接口,但不提供默认实现。须要使用时针对myBatis或者Hibernate,分别写本身的实现类。

原先的类结构上,Controller层只有一个Struts 2.0的action;Dao层只有一个myBatis的Mapper。两个接口都是后来提取出来,计划扩展到SpringMVC和Hibernate的。

Strust2.0通常会为每一个HttpRequest建立一个action实例,并将HttpRequest中的参数根据action的setters/getters方法封装到action中。这就须要action在实例化的时候,同时生成一个参数容器、即类图中param: I的一个实例。然而,根据泛型参数没法直接作实例化。所以,须要为action配置一个参数claz并在Spring IoC中将它注入为I的具体类型。这样才能保证action初始化的同时实例化参数param,并成功读取到HttpRequest中的请求。

MyBatis通常会使用Mapper的类名+执行方法名做为须要执行的SQL-id,并据此id从xml文件中找到、生成实际的SQL。可是,若是直接注入、使用框架提供的MyBatis默认实现类,那么每个查询请求都会按照“xxx.BasicDbMapper.select”这个id去查找SQL,于是也没法找到正确的SQL。为了不这个问题,Basid

DbMapper中使用了入参param的类名+执行方法名做为SQL-id。这样,对“xx.ParamA”的查询请求就会使用“xx.ParamA.select”这个id了。

另外,除了Controller以外,计划扩展到Jms Listener。不过异步消息只有增删改三个操做,就算“半神”吧。


代码

https://github.com/winters1224/blogs/tree/master/code/src/main/java/net/loyintean/blog/sixgod


小结

这个小框架功能很是简单,设计上也很是简单。由于它太简单,少有开发团队愿意在这上面耗费资源。可是,这个框架可以把简单、重复的工做抽取出来,让团队把资源投放在更加复杂的工做中去。

另外一方面,随着REST、微服务等概念的深刻,我认为,每一个系统中的每项资源都应该提供CURD的基本API。这个小框架,可以方便快捷的提供对应的Web API,也能为微服务的快速落地提供方便。