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