王潘章
【摘要】目的:目前JavaScript在前端架構中得到越來越多的應用,該文主要論述了同形JavaScript架構在醫(yī)院信息系統(tǒng)設計中的優(yōu)點。方法:以醫(yī)院OA中風險防控子系統(tǒng)為例,對比了其他基于MVC的設計模式。結果:與傳統(tǒng)架構相比,同形JavaScript架構更加解耦,更加適合大型富前端應用的核心框架。結論:同形JavaScript架構應該是未來Web前端設計架構的趨勢,在醫(yī)院信息系統(tǒng)的應用設計將帶來更好的設計質量與開發(fā)效率的提高。
【關鍵詞】同形;JavaScript;架構;風險防控
【中圖分類號】R722.12 【文獻標識碼】B【文章編號】1004-4949(2015)03-0094-01
1 引言
隨著Web技術的深入應用,醫(yī)院信息系統(tǒng)也更多地采用B/S[1]架構的方式來實現(xiàn)。近年來,Web前端技術得到了高速發(fā)展,更多的技術與框架完全建立在JavaScript/Ajax[2]之上,例如:Backbone,AngularJS等。而隨著Node.js技術的發(fā)展,JavaScript在服務器端也得到了很好的應用。這樣帶來的好處是,無論在客戶端還是服務器端,都可以使用一種語言來實現(xiàn)。但是,由于客戶端與服務器端是完全不同的運行環(huán)境,無法實現(xiàn)真正意義上的應用解耦。
本文以本醫(yī)院風險防控平臺的建設為例,闡述了同形JavaScript技術在信息系統(tǒng)中是如何實現(xiàn)前后端可復用的架構設計。
2 風險防控平臺的功能模塊
衛(wèi)生部于2012年8月出臺了《關于加強公立醫(yī)院廉潔風險防控的指導意見,文件要求醫(yī)院通過“制度+科技”的形式[3],建立醫(yī)院廉潔風險防控平臺[4],實現(xiàn)風險預警、風險分析、風險處置等功能,對權力運行廉潔風險實施動態(tài)防控。風險防控平臺作為一個新的信息系統(tǒng),使用了全新的JavaScript框架,并實現(xiàn)了與現(xiàn)有OA系統(tǒng)的對接。主要包括以下幾個功能模塊:
2.1 職務權力防控
通過定義權力目錄、權力運行流程,協(xié)助醫(yī)院做好清權確權工作。系統(tǒng)采用權力路徑模式,利用外部監(jiān)督、紀檢監(jiān)督實現(xiàn)對醫(yī)院職務權力行使的全程防控,把決策、基建、采購、人事、財務等職務權力納入重點監(jiān)控范圍,通過設置“內控點”實施過程動態(tài)監(jiān)控,確保醫(yī)院各項權利的正確行使,及時發(fā)現(xiàn)廉潔風險,及時警示或糾正,避免問題擴大。核心內容是“三重一大”事項民主決策制度落實情況,主要是:重大事項決策權、干部人事聘任權、項目設備采購權、先進推薦評選權、科研申報管理權和財務資金運行權。
2.2 職業(yè)權力防控
從HIS等系統(tǒng)中抽取數據,通過數據轉換、數據裝載技術,創(chuàng)建數據倉庫,實現(xiàn)對醫(yī)護人員執(zhí)業(yè)行為的監(jiān)管和分析:
臨床用藥:采購藥品使用監(jiān)控、基本藥物使用監(jiān)控、抗菌藥、超限處方;
臨床路徑:臨床路徑入徑、出徑及變異情況;
大型檢查:大型檢查陽性率;
耗材試劑:強化對來源、采購、資質、出入庫、使用的監(jiān)控;
醫(yī)療收費:藥品、耗材加成率,超標準和超范圍收費,退費、欠費;
2.3 患者滿意度管理
通過醫(yī)院終端采集、患者隨訪等多種渠道,實現(xiàn)患者滿意度數據的大樣本、背對背采集,依據多種數據分析模型,實現(xiàn)醫(yī)院的滿意度情況分析,及時掌握公眾對醫(yī)療機構的服務滿意和不滿意的地方,以便相關領導及醫(yī)護人員了解情況,及時發(fā)現(xiàn)問題,提升管理服務水平。
2.4 供應商誠信度管理
建立供應商數據庫,通過資質準入、誠信教育、誠信檔案、誠信評估管理手段,全面采集供應商交易信息、用戶滿意度、表揚投訴、不良行為、禁止行為數據,建立健全供應商誠信檔案,加強供應商風險預警、分析、處置管理,結合職務權力中采購權流程管理和職業(yè)權力中供應商產品異動信息,遏制供應商和醫(yī)院在采購過程中的不規(guī)范行為。
3 同形JavaScript項目架構設計
3.1 Gulp 構建工具
為了系統(tǒng)的開發(fā)過程更加專注于編碼與實現(xiàn)邏輯,大大提高前端開發(fā)人員的工作效率,我們采用了基于Gulp來實現(xiàn)自動化構建管理。Gulp.js 是一種基于流的,代碼優(yōu)于配置的新一代構建工具,提供了高質量的構建插件,使用方便且易于學習。主要包括以下幾個命令:
gulp.task(name, fn) 運行單個任務。
gulp.run(tasks...) 盡可能多的并行運行多個任務。
gulp.watch(glob, fn) 當glob內容發(fā)生改變時,執(zhí)行fn
gulp.src(glob) 返回一個可讀的流
gulp.dest(glob) 返回一個可寫的流
Gulp 對基于JavaScript的項目構建提供了自動化的管理方案,大大節(jié)省了開發(fā)人員每天花在項目構建上的工作量,從而提供了開發(fā)效率。
3.2 CommonJS
設計中遵循了CommonJS;CommonJS是服務器端模塊的規(guī)范,Node.js采用了這個規(guī)范,而且Browserify支持CommonJS。根據CommonJS規(guī)范,一個單獨的文件就是一個模塊。每一個模塊都是一個單獨的作用域,也就是說,在該模塊內部定義的變量,無法被其他模塊讀取,除非定義為global對象的屬性。CommonJS采用require()方法加載模塊;采用exports.report輸出模塊變量。以下為使用CommonJS的代碼樣例:
var risk = require('./risk.js');
exports.report = function () {
console.log("評測報告");}
CommonJS讓我們可以更好地按模塊化的方式組織代碼,并且通過Browserify和Node.js使客戶端和服務器端都更好地支持這一規(guī)范,增加了代碼的易讀性和可維護性。
3.3 React.js
React.js是一個來自Facebook的開源JS庫,用來創(chuàng)建“獨立的視圖組件”。其根本思想與AngularJS的指令或者Polymer的web組件很相似。一個React組件本質上來說就是一個擁有自己作用域的DOM元素。它不能夠直接和你的應用中的其他部分進行交互,無論是JavaScript代碼還是DOM。眾所周知JavaScript的性能取決于操作DOM的性能,針對這點,React.js 實現(xiàn)了虛擬DOM以及DOM diff算法,使得對DOM的操作性能得到大幅地提高,因而其性能是其他框架(AngularJS, JQuery)的數十倍以上。
React.js中另外的一個獨特部分是采用了JSX,它能夠將同代碼一起編寫的HTML轉化成可解析的JavaScript代碼。也有人稱為:“JavaScript XML”,簡稱為JSX。下面就是一個關于React組件中使用JSX的一個例子,下面的代碼將會渲染成一個鏈接。
var component = React.createClass({
render: function() {
returnMore}
});
它將會被轉化成為下面的代碼:
var component = React.createClass({
render: function() {
return React.DOM.a( {href:"/more"}, "More") }
});
3.4 Express.js
Express.js 是一個簡潔流行的 node.js[5] Web應用框架。我們采用Express.js實現(xiàn)了Web請求路由的功能,并且利用React.js技術在服務器端對Web頁面(DOM)進行了預先實現(xiàn),與單頁面JavaScript應用相對比,就大大提高了初始頁面加載的速度。
app.get('/page/:page/', function(req, res, next) {
var page = req.params.page || '0';
if (!validator.isInt(page)) {
return next();
}
makeCall(req, res, next, {
action:ContentActions.list,
params:{
page: page
}
});
});
Express.js支持多種模板引擎,常見的有:Jade、Mustache、Swig等。讓Express.js支持React.JS的視圖,只需要以下代碼來實現(xiàn):
function(res, markup, state) {
state = state || res.locals.state;
var html = React.renderToStaticMarkup(HtmlComponent({
state: state,
markup: markup,
context: res.locals.context.getComponentContext()
}));
res.set({
'content-type': 'text/html; charset=utf-8'
});
res.write('<!doctype>' + html);
res.end();
}
3.5 Browserify
Browserify 可以讓你使用類似于 node 的 require() 的方式來組織瀏覽器端的 Javascript 代碼,通過預編譯讓前端 Javascript 可以直接使用 Node NPM 安裝的一些庫。
Browserify具有一系列靈活的轉換工具,可以在調用require()之前對各種格式的源代碼進行相應的轉換,最終都轉換成JavaScript的形式。例如:
轉換coffee Script文件:
% browserify -t coffeeify main.coffee > bundle.js
本文中用來轉換React JSX文件:
% browserify -t reactify main.jsx > bundle.js
同時,Gulp實現(xiàn)了JSX文件轉換的自動化。這樣,我們可以利用React.js來實現(xiàn)豐富的頁面邏輯,并且按照業(yè)務邏輯對文件進行模塊化管理。Browserify和Gulp會自動將其轉換成前端JavaScript,從而實現(xiàn)了一處構建,多處運行的同形模式。大大提高了代碼可復用性與解耦性,因為我們不在關注于是客戶端還是服務器端,而是注意力轉移到了真正的業(yè)務邏輯實現(xiàn)上來,而這一切還都是同種語言(JavaScript)來實現(xiàn)的。
3.6 Flux
Flux為React.js提供了一組類似于MVC的設計模式。Flux包含三個基本概念:轉發(fā)器、存儲和組件。它的流程是: 轉發(fā)(Dispatcher) -> 存儲(Store)-> 組件(View). 如果一個組件想要改變它的狀態(tài),它需要發(fā)送一個請求到轉發(fā)器中。在MVC設計模式中,你經常會用到 MODEL <-> CONTROLLER <-> VIEW這個流程, 狀態(tài)可以雙向改變。
Store包含了應用的所有數據,Dispatcher替換了原來的Controller,當Action觸發(fā)時,決定了Store如何更新。當Store變化后,View同時被更新,還可以生成一個由Dispatcher處理的Action。這確保了數據在系統(tǒng)組件間單向流動。當系統(tǒng)有多個Store和View時,仍可視為只有一個Store和一個View,因為數據只朝一個方向流動,并且不同的Store和View之間不會直接影響彼此。Flux與MVC[6]相比較,更加適合復雜大規(guī)模應用,因為MVC的模型與視圖間的雙向數據流動會使程序非常難以理解和調試。
3.7 REST API
風險防控子系統(tǒng)作為醫(yī)院OA系統(tǒng)的一個子系統(tǒng),其數據的存儲和工作流的集成要求和OA的其他子系統(tǒng)達到高度的集成。這里的集成通過流行的Web Service的方式來實現(xiàn),具體地說,Web 服務之間通過JSON+Ajax的方式來實現(xiàn)。這樣的集成方式,也很好了解決了業(yè)務層和表現(xiàn)層的分離。本文論述的重點不是如何集成,只是通過公認的集成方式快速高效地實現(xiàn)了OA子系統(tǒng)。達到了各個子系統(tǒng)之間的松耦合,又實現(xiàn)了數據和流程的集中存儲和管理。
4 結論
通過醫(yī)院OA系統(tǒng)風險防控子系統(tǒng)中采用同形JavaScript的架構方式,闡述了該架構方式的優(yōu)點和特點。通過對比,可以看出同形JavaScript更好地解決了前端開發(fā)過程中的耦合性問題以及優(yōu)雅的設計思路給代碼質量和提高開發(fā)效率帶來的益處。同形JavaScript架構是未來Web開發(fā)的趨勢,該文中涉及到的實踐尚處于初步階段,有待于進一步完善成適合醫(yī)院Web前端開發(fā)的一個開源框架。
參考文獻
[1] 劉嵐. 我院藥品不良反應監(jiān)測網絡系統(tǒng)的建設與應用[J]. 中國執(zhí)業(yè)藥師, 2013, 12(14): 44-47
[2] 楊艷麗, 王華民, 曾鵬云, 等. 基于B/S結構醫(yī)院藥庫信息系統(tǒng)的實現(xiàn)[J].價值工程, 2012, 31(16): 179-180
[3] 俞海燕, 陳蓓, 張琛, 等. 基于醫(yī)院OA系統(tǒng)權力風險“制度加科技"防控研究術[J].中國醫(yī)院管理, 2013, 33(6): 16-17.
[4] 顏潔環(huán), 趙婉文, 呂金花, 等. 醫(yī)院廉潔風險防控機制的探索與實踐[J].現(xiàn)代醫(yī)院, 2014, 14(7): 122-124
[5] 鐘強. Node.JS平臺下Web前端架構的研究[J]. 無線互聯(lián)科技, 2013, 12(96): 124/196
[6] 謝晶晶. 基于HTML5的移動辦公應用研究[J].中國數字醫(yī)學, 2013, 8(12): 90-92