標籤:des winform style blog http java 使用 os
電子病曆,到底是用BS還是CS
袁永福
2014-8-19
前言:前幾天下午去開發醫學軟體的S公司,旁聽了他們的內部技術討論會議。他們目前的電子病曆是B/S架構,會上一群人討論起用C/S重構電子病曆系統的可行性,於是引出了本文的題目:電子病曆,到底是用B/S還是C/S。
電子病曆等醫學資訊化系統到底是用B/S模式還是C/S模式。這是一個長期以來困擾著許多甲方和乙方的基礎性的技術問題。過去困擾了,現在還在困擾,估計將來還會困擾。
這個問題真的是可以花開兩朵,各表一枝了。首先說說B/S模式。
B/S模式最為稱讚的特點就是部署、維護和升級非常方便,這是一個無與倫比的優點,一俊遮百醜的優勢,網路上到處都有歌功頌德的文章,我內心也是真心認同和讚揚的。很多時候,你若BS,便是晴天。
對於軟體開發來說,B/S還有一個好處程式功能模組化。要加個功能,也就新增一個WEB頁面,寫上伺服器端代碼,這個操作對已有模組沒有任何影響。因此比較容易做出層次明晰,結構合理,[袁永福原創]能持續可控變化的系統。
得益於傳奇的Macromedia公司和強大的ADOBE公司,B/S的靜態UI展示功能非常好;而隨著技術不斷髮展,B/S的動態UI展示功能也在逐漸增強,比如http://fineui.com就是一個很好的例子。
孫子兵法云:“不知兵之害者,不能盡用兵之利”。同樣的,不知技術之害者不能盡用技術之利。對於電子病曆等醫學資訊化系統來說,B/S還是有著明顯的缺陷,此時C/S程式仍然具有相當的優勢。在此進行對比。
>>頁面狀態
由於B/S的基礎的HTTP協議的無狀態的特性。使得B/S中各個頁面資料交換比較困難,資料交換過度依賴資料庫,大多數狀態資料都需要反覆的儲存和讀取資料庫,增加不少代碼量。醫學商務程序中的業務資料鏈路密集複雜,使用B/S處理起來還是很費勁的,相信廣大程式猿深有體會。
對於來說C/S程式各個表單之間交換資料很方便,表單之間的函數、屬性和事件可以自由的相互調用,能比較簡潔優雅的處理業務資料路由。
>>離線運行能力
B/S程式基本上沒有離線運行能力,所有操作都必須線上執行,中途斷線了,則頁面上的資料全部丟失,使用者體驗非常的不好。相信大家都曾經遇到過,比如敲字發帖或者發電子郵件,辛辛苦苦敲了幾百個字,一提交時才發現網路斷了或者伺服器當機了,文字全部丟失,肯定會抓狂的。
而C/S 程式具有離線運行能力,[袁永福原創]當網路或者伺服器不可用時,可以將使用者輸入的資料暫存在記憶體或者臨時檔案中,等到網路環境好了再上傳,這樣比B/S程式大大改善使用者體驗。
>>瀏覽器安全色性問題
瀏覽器安全色性問題是B/S程式的老大難問題,過去頭疼,現在頭疼,未來還是會頭痛的。相同的頁面,在不同公司的瀏覽器或者同種瀏覽器中的各個版本之間存在一定的顯示差距。比如在設計時“儲存”按鈕放在最下面,對於IE8能顯示,而對於IE7就不顯示,使得應用系統不可用。
規定客戶使用指定版本的瀏覽器也是不可靠的。客戶可能會運行多家公司的軟體產品,各家公司期望指定的瀏覽器版本可能不一樣,此時會產生衝突,讓一家適應另一家都是比較痛苦的過程。
而C/S程式就沒有這種瀏覽器安全色性問題,而且一樣的程式,對於不同版本的Windows系統,其介面也差不多,都是能用的。
>>IE嵌控制項
醫學軟體中一些使用者體驗使用JS/DHTML實在做不出來,於是採用IE嵌控制項的形式,最常見的就是電子病曆編輯器控制項。
所有的IE嵌控制項技術都是不大穩定的,需要配置瀏覽器的安全性設定、需要設定用戶端控制項的更新配置,可能存在少數電腦就是無法自動更新控制項,需要手動進行更新,而且各種IE外掛程式間會相互影響,[袁永福原創]還會受到360等安全軟體的影響。此時B/S系統喪失了部署簡單更新方便的優點了。
在這種情況下,還不如使用C/S程式來做。
>>本機資料緩衝
希臘神話中,西西弗斯因為在天庭犯了法,被大神懲罰,降到人世間來受苦。對他的懲罰是:要推一塊石頭上山。每天,西西弗斯都費了很大的勁把那塊石頭推到山頂,然後回家休息,但到了晚上石頭又會自動地滾下來,於是,第二天又要把那塊石頭往山上推。這樣,西西弗斯所面臨的是永無止境的推石頭。
我們的B/S程式有時候就是西西弗斯在重複又重複的推石頭。醫學軟體在使用的時候需要調用很多字典類型的資料,比如庫存藥品清單、ICD編碼、各種醫學技術名詞、可用的知識庫等等,這些資料記錄都是成千上萬的,可是B/S頁面無法本機資料緩衝,每次重新整理頁面都需要重新載入這些字典資料,增加伺服器的負荷,影響軟體的響應速度,即使採用JS動態載入,也只是治標不治本的。JS無法進行本機資料緩衝,因為JS沒有訪問本地檔案系統的許可權。
而C/S程式可以很方便的進行本機資料緩衝,而且事實上筆者見過的所有的C/S醫學軟體在啟動的時候都會花上一段時間來載入各種字典資料,這樣在運行中就直接使用本機快取的資料,這能提高程式的響應資料,降低伺服器的工作量。
>>軟體自動升級
B/S程式最大的優點就是部署、實施和更新升級很方便。
C/S雖然這方面差一些,但隨著技術的進步,這方面也在逐漸改善。筆者認為在現在的技術條件下,C/S軟體的自動安裝和自動升級真覺得不是問題。這點網路上泛濫成災的流氓軟體就是很好的證明。再比如QQ用戶端軟體,幾乎每台電腦都會安裝,也很好的解決了部署升級問題。
現在用戶端絕大多數還是微軟的Windows系統,微軟針對軟體的部署和升級提供了很多底層的支援,包括SmartClient/ClickOne技術等等,[袁永福原創]這些都為C/S軟體的自動化部署升級帶來很大便利。
>>運行效能
現在的B/S程式大量依賴JS技術。而JS語言是解釋方式啟動並執行,很靈活,但容易出錯,而且運行速度慢。當JS太多時,比如前頭提到的S公司,他們的JS代碼量佔40%,此時瀏覽器經常報JS運行逾時的警告資訊。
而C/S程式都採用編譯性語言,會進行嚴格的語法檢查、很多錯誤都在開發編譯階段能發現,這能提高代碼的運行速度。即使遇到耗時的操作,也可以使用多線程操作來改善使用者體驗。
>>代碼規範
B/S程式的用戶端程式設計語言是JS,JS是物件導向的,單不是基於對象的,而且很多公司重視程式碼的品質,但不大重視JS的代碼品質,因此造成JS代碼的臃腫,出現大量的重複代碼。
相對來說主流開發組織對C/S的程式設計語言是講究規範的,比如C#/JAVA等,還有專門的語言規範檢查工具,而且C/S的程式設計語言大多是完全的物件導向的,能很好的實現代碼重用,重構也很方便。[袁永福原創]主流開發組織也重視程式碼程式庫的積累和維護。
>>國際化
所謂國際化就是推出軟體的多語言版本。比如電子病曆系統的簡體中文版、繁體中文版、維文版、英文版之類的。
目前中國國內的醫學軟體產品基本上不考慮國際化。不過有條件的公司應該還是要考慮到軟體產品國際化。
B/S軟體比較難於做到軟體的國際化,因為WEB頁面中的文字都寫入程式碼在HTML代碼中,同時維護WEB頁面的多語言版本工作量很大,而且JS/DHTML比較難於實現字串資源的各個版本。
相對來說,C/S程式比較容易實現軟體的國際化。比如對於VS.NET的WinForm表單,可以在設計階段來配置多語言版本的資源檔。例如所示:
這是VS.NET中一個WinForm表單的相關檔案。在這裡dlgSpecifyPaste.ar.resx是維文版的資源檔,dlgSpecifyPaste.en.resx是英文版的資源檔,dlgSpecifyPaste.resx是預設的簡體中文版的資源檔,dlgSpecifyPaste.zh-TW.resx是繁體中文版的資源檔。
使用這些資源檔,[袁永福原創]可以讓表單在不用的語言環境下顯示不同語言版本的內容,不過都表達相同的意思。
編碼中需要的字串也可以另外放在資源檔中方便的實現多語言版本。這樣編譯結果就是一個主程式配上多個語言版本的資源檔。比較輕鬆的實現了國際化。
>>使用者行為
一些使用者行為在B/S中沒法很好的處理。最常見的就是直接關閉瀏覽器。一些瀏覽器提供視窗關閉事件,JS可以響應這個事件來進行處理,不過這存在瀏覽器安全色性問題,可能在某些情況某些瀏覽器中JS無法響應這個事件。
另外就是快顯視窗功能了。瀏覽器可能會阻止彈出式的視窗。在彈出式的視窗中的JS效果和普通表單中的JS效果還可能不一樣。這些就是需要花不少時間調試和配置的。
而對於C/S程式就沒有這種問題了。
從上面分析可以看出B/S也不是完美,C/S也是有其優勢的,實際運用中不應該一刀切。
------- 超越B/S和C/S ----------
現在有一種技術流派,想要超越B/S和C/S之爭的,筆者也支援這派。筆者長期做UI層開發,那麼就從UI層開始說起。
現在所有的醫學軟體都是圖形化使用者介面,對於C/S程式,寫C#代碼調用DrawString(),DrawLine(),DrawImage()之類的GUI API來繪製使用者介面;而對於B/S程式是伺服器端寫代碼輸出HTML代碼,然後發給瀏覽器讓其解釋這個HTML代碼來“繪製”使用者介面。
因此可以抽象出來看,程式猿都是花大量的代碼來繪製圖形化使用者介面,只不過一部分代碼輸出圖形繪製指令,一部分代碼輸出HTML代碼。但最終目的都是一樣的。
另外程式猿還需要寫大量的代碼來讓圖形化使用者介面和使用者互動,都需要響應KeyDown/MouseClick等事件,這點大家的寫的代碼都很類似。最終目標也一樣。
按照這種思想,B/S和C/S的理解可以如下:
C/S程式 |
資料庫伺服器→應用軟體→介面呈現資訊(DrawString等指令)→GUI For Windows |
B/S程式 |
資料庫伺服器→應用軟體→介面呈現資訊(HTML代碼)→GUI For Browser |
兩者邏輯上的高度相似性可以很容易聯想到物理學中引力和電磁力邏輯上的高度相似性。物理學中正在謀求統一場理論,那麼我們也可以謀求B/S和C/S的統一。
因此B/S和C/S呈現使用者介面的代碼雖然語言不同、代碼執行的地方不同,但邏輯是相同的,因此邏輯上完全可以統一起來。以此類推,對於商務邏輯執行也是這樣的,這就是B/S和C/S統一的理論基礎,[袁永福原創]具體表現形式可以是OOP、AOP之類的。
按照B/S,C/S的統一理論,醫學軟體可以劃分為以下幾個部分:
- 資料庫伺服器。SQL SERVER/ORACLE/NOSQL之類的。
- 商務邏輯執行層。執行醫學商務邏輯的代碼,這個層面純粹執行業務功能,沒有使用者介面。而且考慮到B/S應用應該是多安全執行緒的。
- B/S伺服器應用程式層。運行在WEB伺服器上的,直接調用商務邏輯執行層來實現業務功能。
- 遠程調用封裝層。對商務邏輯層執行層的功能進行封裝,能方便的進行遠程調用,這個遠程調用就是基於XML的WebService或者基於二進位的JAVA/.NET Remoting。
- C/S用戶端軟體。用戶端軟體通過網路調用遠程調用封裝層來執行商務邏輯。
對於這種架構模型,如果商務邏輯執行層和B/S伺服器應用程式層編譯在一起就是傳統的B/S系統;商務邏輯執行層和C/S用戶端軟體編譯在一起就是傳統的C/S系統。如果5個部分都分開,那麼就是同時支援B/S和C/S的,這樣軟體具有強大的擴充性和生命力。
迴歸到筆者的老本行,電子病曆編輯器。編輯器控制項提供WinForm版本和ASP.NET版本的。WinForm版本支援所有的功能;不過受限於當前技術水平,ASP.NET版本只能唯讀閱讀病曆文檔內容,而無法編輯修改。因此建議在開發常規電子病曆系統時採用C/S模式,對於互連網應用,比如公衛平台之類的,也是建議新的B/S和C/S統一模式。對於行動裝置 App可以採用傳統B/S模式。
最後想總結一下,[袁永福原創]孫子兵法又說了:兵勢如水。小平同志的白貓黑貓也是這個理。筆者覺得開發軟體也應該“兵勢如水”,不必拘泥於B/S,C/S之類的條條框框。怎麼適合需求就怎麼做,靈活變幻開發策略,以最優的路徑做出符合客戶需求的軟體。
【作者簡介:袁永福,微軟MVP,資深軟體開發專家,著書立作,就職於南京都昌資訊科技有限公司(http://www.dcwriter.cn),現從事於電子病曆編輯器、時間軸等醫學用軟體組件的研發工作。部落格網址http://www.cnblogs.com/xdesigner。】