這個方案並非我在系統設計方面的最先一次嘗試。但它在提升開發效率方面,是效果最爲顯著的一個方案。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有所不一樣。
類圖
「六神」的主要類圖中,以接口定義居多。其中的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,也能爲微服務的快速落地提供方便。