開發框架要考慮的面太多了:安全、穩定、性能、效率、擴展、整潔,還要經得起實踐的考驗,從零開發一個可用的框架,是很耗時費神的工作。網上很多開源的框架,為何還要自己開發?我是基於以下兩點: 1. 沒找到合適的:安全、穩定、簡單、易用、高效、免費; 2. 想成為架構師; 於是就自己動手,參考網上開源的項目 ...
開發框架要考慮的面太多了:安全、穩定、性能、效率、擴展、整潔,還要經得起實踐的考驗,從零開發一個可用的框架,是很耗時費神的工作。網上很多開源的框架,為何還要自己開發?我是基於以下兩點:
- 沒找到合適的:安全、穩定、簡單、易用、高效、免費;
- 想成為架構師;
於是就自己動手,參考網上開源的項目和借鑒網友的設計思路(特別是蕭秦系列博文),結合自己的實踐,開發了一個簡單、易用、高效的的框架,雖然不完善,但也能解決現實中的問題。不過隨著見識增廣,發現沒負責過千萬級別的項目難以成為架構師,也不可能開發出一個完美的框架。那就先開源出來,後面慢慢維護和完善。
一、框架結構圖
二、分層
從框架圖看出,按代碼結構業務來分為 5 層:
- Web: 展示層
- WebApi: Http 接收與響應
- Service: 業務邏輯和數據處理
- EasyCore: 半ORM(Easy.DataProxy, Easy.Office, Easy.SqlConfiguration)
- Model: 實體
對應解決方案的項目結構:
按功能角度分為 3 層:
- 淺藍色的: 展示層
- 深藍色的: Http接收與響應層
- 淺橙色的: 業務邏輯和數據處理層
按業務分為 2 層:
- 淺藍色的: 展示層
- 淺橙色的: 業務邏輯和數據處理層
也就是經典的 3 層架構, 我只是把後面的業務邏輯層和數據處理層合拼為 1 層。理論上把業務邏輯和數據處理分離是很合理的,但現實是數據處理往往就是寫 Sql, 而 Sql 不只是簡單獲取數據,很多時候會耦合有大量的業務邏輯在裡面, 導致程式員去處理業務時,把一個業務需求拆分到 2 層去處理,這樣不能享受分層的好處,反而帶來以下副作用:
- 破壞單一業務的內聚性;
- 分散程式員的註意力:一條很合理的線性思路,分離到 2 個項目去實現;
- 增加程式複雜度:看懂一個業務代碼的實現,要同時看兩個層的代碼;
當然把業務和數據處理分層對規範化多人協作的大型項目是很好的方式,幫助解耦、降低複雜度,不過對沒有嚴格規範分層代碼的三少項目(錢少、人少、時間少),這就不是好事了;分層是一種技術工具而不是規則,要根據實際情況找到適合當前項目和團隊的分層方式。對於中小型、註重寫sql的項目,更適合把業務和數據處理放到同一層。
三、技術棧
前端用 mvvm 模式把頁面呈現和js業務代碼分離:
引用庫:
- Easyui 1.4.0: 展示UI, 有做微小修改以適應框架;
- knockoutjs: 實現mvvm;
- profoundgrid: 頁面佈局;
工具:
後端實現 RESTful Api:
引用庫:
- Asp.net WebApi: 實現RESTful api;
- autofac: 依賴註入;
- JWT: 實現Oauth2, 用 token 授權,實現跨域;
- fluentData: 支持多資料庫的數據持久,有改動以適應框架;
- log4net: 日誌組件;
工具:
- .net4.5;
- vs2015;
- mariadb: mysql 資料庫的一個分支;
- T4模板:代碼生成器;
四、項目說明
後端
│Grissom.CMS
│
├─1-Model -- 實體類
│ ├─generation -- T4模板生成
│
├─2-Services -- 業務邏輯和數據處理層
│ │
│ ├─custom -- 業務代碼寫在這裡
│ │
│ ├─generation -- T4模板生成
│
├─3-WebAPI --
│ │
│ ├─AOP -- 橫向切入:異常日誌記錄
│ │
│ ├─APIs -- 公開的 API 寫這裡
│ │
│ ├─App_Data
│ │ inital.sql -- 資料庫腳本
│ │
│ ├─Auth -- 實現跨域和Token授權
│ │
│ ├─Log -- 日誌
│ └─SqlConfigs -- 配置增刪改查的 sql xml
│ SysRole.xml
│ SysUser.xml
│ VideoMain.xml
│
├─Core -- EasyCore 自動化增刪改查
│ ├─Easy.DataProxy -- sql配置 解析器
│ │
│ ├─Easy.Office -- 導入導出 excel
│ │
│ ├─Easy.SqlConfig -- sql配置模型
│
│
├─Libs -- dll 庫
│
其中,Model, Service 都用 T4 模板實現代碼自動生成, 前面說了 Service 就是業務和數據處理的核心項目。
前端
├─1-content -- js, css 系統通用文件
│ │ comData.js -- 公用庫: 配置 api 伺服器
│ │ config.rb -- compass 配置文件
│ │ Gruntfile.js -- grunt 配置文件
│ │ package.json -- nodejs 初始化配置文件
│ │
│ ├─asset -- 資源
│ │ ├─css
│ │ │
│ │ └─js
│ │ │
│ │ └──core
│ │
│ ├─icons -- easyui icons
│ │
│ ├─images -- 圖片
│ │
│ └─node_modules -- nodejs 引用庫
├─home -- 主頁
│ index.html
│ index.js
│
├─sys -- 系統模塊
│ ├─role -- 角色管理
│ │ │ edit.html -- 編輯頁面
│ │ │ index.html -- 列表頁面
│ │ │
│ │ └─viewModel -- 模型
│ │ edit.js
│ │ index.js
│ │
│ └─user -- 用戶管理
│
└─video -- 視頻模塊
home 是容器,sys, video 是對應系統的業務模塊,role, user 對應系統表:SysRole, SysUser。前端核心庫是 1-content/asset/js/core 下麵的js, 其實就實現的通用的數據綁定和也後臺數據交互功能。
1-content 中只需修改 comData.js 的 api 伺服器配置 com.apiDomain = "http://localhost:2717";
其它都是通用的,所以我用grunt 把通用的庫和css 分別合併成 all.js,all.css。當然要做修改,可安裝 nodejs, grunt, 參考grunt。
五、簡單應用:
具體實現參考底部的 demo, 流程如下:
1) 修改資料庫伺服器: 有 4 個地方要改的, 其中 3 個是 T4 模板, 1-Model/generation/ModelTemplate.tt, 2-Services/generation/ModelTemplate.tt, 2-Services/custom/ModelTemplate.tt,3-WebAPI/web.config;
2) 重新執行 T4 代碼生成器:修改或添加新表後,打開T4模板文件,然後保存一遍,就會自動生成了,有 3 個 T4 模板文件: 1-Model/generation/ModelTemplate.tt, 2-Services/generation/ModelTemplate.tt, 2-Services/custom/ModelTemplate.tt;
3) 添加API: 在 3-WebAPI 項目下添加對應的 api controller;
4) 添加sql 配置: 在 3-WebAPI 項目下的 SqlConfigs 文件夾添加對應表名的 sql xml 文件;
5) 轉到前端: 在根目錄下添加模塊文件夾和對應的表文件夾,並添加 index.html 列表頁面 和 edit.html 編輯頁面, viewModel 文件夾添加模型js文件;
6) 運行 WebApi, 再瀏覽頁面;
六、預覽:
七、總結:
該框架有 3 個核心點,以後單獨 blog 來詳細展開描述,不然你看不到框架的強悍所在:
- 後端 EasyCore(Easy.SqlConfiguration, Easy.DataProxy, Easy.Office): 直接通過一個簡潔的 xml 文件配出對錶進行增刪改查功能;
- 前端 viewModel.common, viewModel.search,viewMode.edit:結合 knockoutjs 和 jeasyui 實現 mvvm;
- 前後端交互的數據結構:
{master:{inserted:[{data:{},children:{c1:{inserted:[],updated:[],deleted:[]}}}]}}
, 該結構能標識出單表、多表、主從表的混合批量新增、修改、刪除狀態, 後臺分析該json格式的數據結構,結合 sql 配置,就能實現自動化資料庫操作;
框架並不完善,也不一定適用於你,但歡迎提意見,後續完善。PS: 該框架已經用到生產環境了。
八、源碼 https://github.com/grissomlau/Grissom.CMS
初始化登錄名:admin, 密碼: 123