醫學資訊化領域的軟體設計模式

來源:互聯網
上載者:User

如果說上一篇關於醫學資訊可靠性的討論還是殘留了一些商業方面的味道(雖然名義上是要迴歸技術,但還是涉及到了一些業務方面的問題);那麼,這篇打算把技術方面的牛角尖繼續鑽下去,討論一下設計模式,而且:

- 要只是討論整合領域設計模式好像還不過癮,那就先從整個醫學行業軟體的角度開個頭,不過不包括嵌入式系統;
- 都是些常見的技術方案,未必是最佳化的,也不會涉及任何商業機密,因為一些公開的出版物和網路社區裡面都有相關描述。
- 對於這些技術方案,不會進行明確的分類,也不可能很全面,大都只是自己記憶中印象深刻的,這裡畢竟只是隨筆,不是論文。

需要注意的是,現在我們要考察的是這些資訊系統的另外一面,這一面展現給我們的只是一些技術的抽象,並不會存在完整的業務圖景。

--

在進入正題之前,還是忍不住想抱怨一下業界的浮躁,同時也是對自己的警戒。

最近去聽了某位號稱為軟體架構大師的講座,講座之前看到講義的時候我已經心存質疑,在現場聽了5分鐘,驗證了這種質疑,講座之後聽到同事的議論,更加堅定了我的判斷。不過我只做了5分鐘的聽眾,不好妄加評論,只是感覺演講中用到的比喻多到幾乎掩蓋了工程實踐了。本來軟體就是一個比喻泛濫的領域,從蓋房子到拍電影,從飛機設計到汽車工廠,什麼都拿來跟軟體撤上關係。難道軟體的地位真的就如此低下到要用這麼多東西來撐門面嗎?這回甚至把中國文化也扯進來了。

其實我聽過的專門針對軟體架構的講座並不多,也沒法做個全面的比較,只是感覺溫昱老師還是把設計的理論和工程的實踐結合得比較好的,也不乏啟發性。如果要聽中國文化,我還是非常推薦餘秋雨的。如果某天餘秋雨先生講軟體架構,我倒一定要去聽聽。

關於業界的浮躁,還有一個方面的表現,主要發生在銷售人員和技術人員之間。這應該是程式員圈子裡老生常談的話題,這裡還是忍不住想炒一下舊飯。總之銷售人員總是覺得技術人員過於理想主義,技術人員又覺得銷售人員太過現實,通常銷售人員又比較能說會道,也比較aggressive,技術人員大部分都沒這麼能說,人也比較nice,這場爭論的結果可想而知。

這種現象在中國也許會表現的更加明顯一些,畢竟中國還是IT產業的低端。國外的情況不太清楚,但至少還有些高端的技術論壇,讓技術人員自己也有個可以說話的地方。不過有個事實是大家公認的,西方文化更加尊重技術創新,東方文化更加註重人際交往。美國的不少大公司(Kodak,GE,MS等)的創始人首先都是技術人員,有些甚至是技術很牛的技術人員(很多內部資料可能會顯示BillGates並不是個技術天才,那也是他轉型成為商務人員之後的表現而已),正是這些人還是技術人員的時候創造了這些個商業平台,然後商務人員讓這些平台最終取得了成功。

然而,在我曾經工作過的一個技術型的公司,技術和市場策略都是對的,甚至在國內是相對領先的,一些理念的正確性也不斷地被行業的發展所證明,但是在實施具體的銷售策略和方案的時候遇到了近乎瘋狂的對手:這些對手向客戶免費提供軟體。注意,這跟互連網行業不同,這種免費並不是一種商業模式的創新,而是把整個市場變成一個低服務品質,高政治回報的地獄。這也就是很多銷售人員整天跟我們談論的現實。這些銷售人員喜歡研究甲方組織內部人與人之間的關係,而不會去研究自己正在銷售的技術將如何改變世界:而這種取捨正好創造了他們的驕人業績,以及我們賴以活命的薪水。

還有一個有趣的現象,銷售人員與IT Pro(營運人員)的一個共同點是對數位極端敏感,前者特別注意貨幣的金額,後者特別注意裝置的參數,這兩種數字之間通常有著某種天然的映射,於是這兩種人往往十分投緣。他們偶爾也會討論技術,每每提到的時候,都會不屑於顧地說,嗨,這些都是程式員的活。

不過話說回來,上面說到的每一種人在每一個成功的組織裡面都缺一不可,團隊的作用就是就是讓各種奇形怪狀的人協同工作,最終達到1+1大於N的效果。

總結一下,每個人都應該把自己擅長的事情做到最好;每個人都應該尊重其他人的勞動,尤其是創新性的勞動。

--

我們還是先從前端應用開始,比如說各種工作站。

前不久我們要做一個支援可用性的技術方案,我查了一下SEI的書(雖然有點學院派的嫌疑),用以支援可用性的架構設計決策竟在一定程度上跟可修改性(即應用程式的靈活性)密切相關,其中的假設是在程式寫好之後,使用者和UI設計師還是會頻繁地要求修改使用者介面。回想一下,還真的蠻有道理。早期很多行業軟體的使用者介面,基本上是在客戶化開發的階段才能夠定型的,於是一些公司也會讓工程師在項目中的某個階段常駐醫院。儘管這種方式會一定程度上增加品質控制和專案管理的難度,但對於工程師來說,這是獲得領域知識最好的途徑。

我們熟知的MVC是用來支援可用性的最常見的設計模式之一,後來還發展到MVP和MVVM,它們的核心思想都沒有改變,都是讓介面和邏輯盡量地分離。我們看到的很多技術也是基於這種思想,比如MFC的文檔視圖模型,ASP.Net的Code Behind等。當然,也有一些介面設計方面的Best Practices,比如必要的支援資訊、條理化的介面分區和Step By Step的操作等,這些通常屬於詳細設計時候要考慮的問題。

如果在可用性方面繼續深究下去,就要走出電腦螢幕的框框,在醫生的整個工作環境的角度來考慮了。比如很多影像診斷工作站提供了1+N的顯示器組合;很多臨床工作站則是在醫生的辦公桌裡挖個洞,把顯示器嵌在裡面,醫生則是趴在他早已習慣的一個玻璃板上工作。這就造成了一個有趣的結果,有些醫生總是仰著頭,有些則總是低著頭。以前有個放射科醫生還跟我抱怨,豎屏顯示器太高了,看久了會得頸椎病,然而我們卻沒有辦法賣給他一張更高的椅子。

如果說很多人還是喜歡把MVC當作一種架構模式,那麼State模式應該是一個用於前端應用的典型設計模式之一了。尤其對於一些複雜的使用者介面或者通訊介面,比如影像工作站的看圖介面上的滑鼠控制,以及實現了DICOM協議的網路通訊模組。這裡就不往實現細節方面進一步展開了,總之用State模式來實現的狀態機器,一大好處就是當有新的狀態,或者新的變遷要加入的時候,修改代碼變得十分方便,其原理是用虛函數表取代了複雜的條件判斷語句。而且State模式所提供的效能已經能夠滿足這個領域的需求了,在其他一些領域,比如嵌入式裝置,也許物件導向的State模式會顯得比較臃腫;在電腦遊戲領域,有些人也許更加喜歡決策樹,而不是狀態機器。提到使用者介面,很多人還會想到command模式和strategy模式等,當然它們也很有用,很多時候可能我們一不小心就用上了。但事實上,undo的功能對於很多工作站來說似乎是一種噱頭,我見過很多醫生的操作習慣是,如果把映像調亂就直接按reset鍵回到初始狀態,然後重新開始調。當然更多的時候,他們根本不願意調,病人流量實在太大了,用預設的WW/WC或者曲線來看看就行了。醫生畢竟是醫生,不是平面設計師。

在以文文書處理為主的HIS或者LIS工作站上,State模式也沒有什麼用武之處,也許這些前端應用更需要使用一些實現模式,而不是設計模式。比如在載入大規模資料的時候,使用後台線程,來實現介面的互動性,這裡面也不存在太複雜的線程同步問題,只是需要注意GUI對象一般是不能跨線程訪問的。因此,盡量避免多線程,是一條最基本的也是最難以遵守的設計原則。至少,如果是在視窗載入的階段,可以把資料載入的工作放到一個timer事件裡面,等零點幾秒視窗畫完之後,再來載入資料和不斷更新介面,這樣使用者似乎會感覺好一點。但大多數其他的時候,後台線程還是必須的,而且現在雙核的電腦越來越多了,不多開點線程還真有點過意不去。

在早期的應用中,MFC為介面程式中不同模組之間的互動提供了天生的便利,它主要是依賴Windows的訊息迴圈,將互動的處理序列化,而不是象VB和WinForm這樣,讓程式員習慣於更多地進行直接和粗暴的同步調用。WPF則在這方面更進一步,它使用所謂的dispatcher來代替WinForm的Invoke,據說可以避免尋找控制項樹從而實現更快的調用。現在我對WPF的瞭解還比較膚淺,只是聽說它整個視窗,不管裡面有多少個控制項,都只佔用一個控制代碼,並且允許開發人員充分利用非同步(即多線程)實現更好的互動性。從而避免了象WinForm那樣,在運行長時間處理的時候,要調用DoEvent來處理介面響應。

以前我在使用WinForm的時候,就碰到過一個鬱悶的問題,跟DoEvent有關。放射領域通常有病人、檢查、序列、映像幾級對象,在使用者介面上通常需要用多級列表的方式來展現這些對象,我們一般不在醫生操作的介面的過多的使用樹型視圖,因為它在操作大規模資料的時候,用起來沒有列表來得簡單。在這種分級列表上,一個常見的介面邏輯就是,在病人列表中選中一個病人的時候,在檢查列表中顯示這個病人所做過的檢查,選中一個檢查的時候又會重新整理序列列表,依此類推。由於大多早期的PACS伺服器都不支援多級查詢,這些對象只能一級一級地展開,因此每次展開,即載入下一級資料的時候,都會發生一次網路通訊,並且佔用一點時間。為了在這段時間裡面保持介面響應,我們最初的做法是,每載入到一個對象,就調用一次DoEvent,即把當前訊息迴圈裡面堆積的訊息全部分發出去。這種囫圇吞棗的做法有一個嚴重的後果,如果使用者在選中一個病人之後立即選用另外一個病人,那麼這兩個病人的檢查就會以某種難以預料的方式重疊出現在檢查列表中。因為你還沒有處理完第一個病人的時候,調用了DoEvent,使得選中第二個病人的滑鼠事件開始被處理了。

解決的辦法很多。悲觀的辦法:就是不要使用DoEvent,在網路速度慢的時候讓醫生多忍受一下。無賴的辦法:也還是不用DoEvent,而是讓伺服器支援多級查詢,第一次查詢的時候有點慢,展開的時候就很快。由於醫生一般不會設定太寬泛的查詢條件(一般都是近幾天,或者指定ID),所以不會感覺到查詢很慢。又由於大多PACS都會採用集中式儲存,即採集到的映像都匯總到同一個技術比較先進的PACS伺服器上,這種伺服器一般都支援多級查詢;如果醫生非要把查詢目的地指向另外的某個廠商的裝置或者伺服器,就可以順便把皮球踢過去。真正負責任的辦法:可以使用DoEvent,但是要用某種方式把列表上的滑鼠選中事件排隊一下,一個挨一個地處理,排隊的方式很多,可以自己寫,也可以使用線程池。有時.Net提供的MethodImplOptions.Synchronized鎖定也可以當作一種簡單易用的排隊機制。

前面說了一些案頭應用方面的模式,好像我們也不應該忘記WEB。不過至今為止,地區醫學還沒有普及起來,醫學資訊化的重心還是在院內的企業級應用方面的。再加上醫學領域的使用者介面大多互動功能都比較複雜,不管是醫生寫病曆、下醫囑還是看影像,或者是登記員輸入病人資訊,象WEB這種基於無狀態的基礎設施來構建的使用者介面,似乎難以勝任。在院內系統中,WEB通常用在幾個方面,一個是讓院長主任之類的人看看報表,或者是讓其他部門的無關人等看看報告或者醫囑處理進度;另外一個則是讓WEB來承載一些功能複雜的ActiveX控制項,或者負責前端程式的部署,並美其名曰智能用戶端,這些其實都是案頭應用的擴充了。

現在看來,SaaS和雲端運算的浪潮正在把傳統的企業級應用往互連網上推,使得軟體產業不得不在商業模式和技術架構上進行一次重大的調整(見前面幾篇文章)。在這次浪潮中,前端應用領域的技術新秀應該非RIA莫屬了。記得當時我在寫“整合的故事-案頭整合”的時候,曾經表達過對ASP.Net的PostBack和Ajax的不同意見,至今為止,我還是堅持自己的看法,並且深切感覺到WPF迴歸DOM編程模型的良苦用心。這種多年來只是非主流地存在於瀏覽器端指令碼中的實現模式(即標記式的介面展現指令碼,以onclick之類的方式串連到實現功能的代碼),也許將會成為我們下一代使用者介面的基礎。與這種實現模式形成完美呼應的,則是RIA這種部署模式,它把原來的富用戶端程式host到瀏覽器中運行,它擁有本地記憶體,並且能夠跟背景服務進行豐富的互動,部署起來也比智能用戶端更加輕量化。另一方面,RIA也會促使WEB迴歸到它的真正本源,PostBack和Ajax則會面臨生存危機。

--

現在來看看後端應用。這裡之所以用前端和後端,而不用伺服器和用戶端,作為區分,主要是因為前者似乎更多是指邏輯上的layer,後者更偏向於物理上的tier。而很多醫學應用,比如近幾年很多國內PACS廠商賴以生存的單機版工作站和小型化的解決方案,tier的概念就遠沒有layer來得明顯了。

不過不管是多大或者多小的PACS,只要我們考察的視線從前端的介面往後端的方向稍微推進一點,就必然會碰到一個共性的問題,即如何管理這些巨大的影像資料,它們是如此的巨大,以致於你必須考慮它的傳輸鏈條中的每一個環節,從顯存,到記憶體,到磁碟,到網路,到伺服器,到RAID,到光碟片塔或者磁帶庫。因此,一個完整的PACS技術方案,通常由各個方面的專家通力協作完成的,包括顯示器、伺服器、網路、存放裝置、列印裝置、軟體等。對於軟體開發人員來說,通常主要關注的是兩個問題,一個是在前端介面上如何響應複雜的使用者操作,並且根據這些操作的語義在顯存、記憶體、磁碟和網路上管理這些映像;一個是在後端的傳輸鏈上,如何?一個通常是由RIS的一些商務程序相關的訊號驅動的映像預取邏輯,讓映像智能化地在本機磁碟、網路、伺服器的線上、近線和離線儲存之間流動,並美其名曰讓圖找人而不是人找圖。

有人曾經對PACS中的資源管理員模式做過一些系統的研究,寫成一本書叫做Pattern-Oriented Software Architecture: Patterns for Resource Management。遺憾的是我一直沒有時間來仔細研讀,好像記得裡面有提到類似代理的模式,有效地管理了使用者介面上的預覽圖和真實映像之間的關係。書中應該還有其他的模式,用到的時候再去看吧。還有一些簡單的實現模式,倒是曾經用到過的,這些模式通常跟影像類型相關。一些早期的PACS都是跟裝置捆綁在一起銷售的,這些PACS通常叫做miniPACS,以區別於部門級和全院級的PACS。做普放裝置起家的PACS廠商開發的工作站,用來開啟CT/MR這些斷層映像,有時會非常的慢。因為一個普放檢查裡面的映像通常不會不多,而且每張圖又很大,醫生覺得等個幾秒鐘似乎不是大問題,因此它們通常是把整個檢查的映像載入上來,這樣也便於應用懸掛協議;但對於斷層映像,醫生當然會希望載入到第一張圖的時候就開始顯示,然後可以邊瀏覽後台邊載入,全部載入完成之後再點擊按鈕來選擇特定的懸掛協議,由於斷層映像都很小,在介面上基本上不會感覺到任何的延遲。反過來,對於一些做斷層映像出家的PACS廠商開發的工作站,在用滑鼠對普放映像進行WW/WC調整的時候,有時也會非常的慢,感覺螢幕一抖一抖的,而且不管怎麼調,相比起來還是沒有其他工作站顯示得好。事實上,其他工作站在用滑鼠來調整WW/WC的時候,調節和顯示的是一個解析度稍微低一些的圖片,這樣在調節大幅映像的時候,使用者響應會好一些,而且對於一些普放映像,用曲線(LUT)代替線性WW/WC來做顯示和調節,映像品質也許會好很多。另外,除了這些跟醫學領域密切相關的模式之外,只要是做映像顯示和處理的程式,都會用到一些領域無關的實現模式,比如用雙緩衝區來避免直接寫屏導致的重新整理時螢幕閃爍等。

另外,隨著CT的排數越來越多,有時(比如在會診的時候)在工作站上需要載入的映像的大小會遠遠超過實體記憶體,這時候就需要考慮如何管理超出實體記憶體的這部分資料(而不是理想化地通過基於關鍵對象的複雜流程來減少前端的壓力)。對於一些沒有顯示出來的斷層映像,暫時把它們從記憶體裡釋放掉(或者根本不載入),也許會比把它們留在虛擬記憶體(由作業系統來管理的一個磁碟地區)中會好一些,似乎檔案系統的緩衝也會協助我們減少重新裝載映像的時間。但這又會引發新的問題,對於暫時被釋放掉的映像,如何保持它們的顯示狀態呢?對於一張就十幾兆普放映像來說,檔案系統的緩衝能夠保證足夠的效能嗎?

最終,人們發現不同類型影像的載入和瀏覽方式之間的差異,以及不同醫學領域的醫生對同種類型的影像的使用方式之間的差異,實在難以調和。於是,我們只能做一些分解,降低一些業務無關的因素在技術實現上的耦合。具體點說,就是把不同類型的影像放到單獨的模組中,每個模組有自己的載入、顯示、處理、記憶體管理邏輯和特殊的瀏覽/報告工具。然後把這些模組以外掛程式的方式組裝到工作站的基礎架構中。這樣,在技術上,基礎架構可以封裝共用的模組,比如網路通訊邏輯、以及前面提到的分級儲存邏輯的前端實現,從而提高新功能的開發效率。在業務上,可以滿足更多的映像顯示和處理的要求,這樣工作站就可在各種不同的領域,不光是放射科,還有骨科、外科手術室、會診中心甚至特殊的診所(比如牙科,或者是獸醫科)等使用,不同領域的醫護人員還可以使用專門為他們的領域而定製的模組。

不久前,當我看到正在討論中的DICOM Supplement 118 (Application Hosting)的時候,實在感慨萬千。記得幾年前寫過一篇文章An open architecture for medical image workstation,SPIE Conference 2005,說的也是類似的事情,而當時我們模仿的對象就是Syngo。

Application Hosting是個有趣的東西,它初看起來有點像CCOW。事實上,它更像是為映像工作站而特別設計的一種介面標準,讓不同的廠商甚至可以在同一個進程內協同工作。如果它真的變成DICOM的第19章,對我們來說意味著什麼呢?首先,主流的PACS廠商之間的競爭焦點將會集中到平台,而不是單個的產品。整體的解決方案也不再是幾個產品的簡單組合,而是從背景雲一直延伸到前端的外掛程式架構的一體化平台,以及在這個平台上啟動並執行各種下遊廠商所提供的針對特定技術或者業務領域的模組。到時候,互連網上甚至還會出現一些象蘋果的App Store那樣的醫學影像領域的模組集市,開發人員和使用者可以在上面直接進行交易,就像菜市場那樣。

講到這裡,千篇一律的爭論又開始了。現實主義者也許會問,這些東西是很好,但你的業務能活到這些東西能賣錢的那一天嗎?理想主義者回應,好吧,你就用自以為足夠的解決方案繼續忽悠你的使用者去吧,說不定哪一天,你就只能到菜市場上混了。隨著技術的不斷髮展,這種爭論會不斷地繼續下去,最終也不會有贏家。真正的贏家,根本就沒有時間去跟你爭。

當然,我還是願意保守地相信傳統的基於獨立解決方案的商業模式和技術架構還會存在相當長的一段時間。尤其在國內,這種傳統的模式甚至還沒有完全成熟,單機工作站還在大行其道。在包括醫學在內的很多傳統行業,人們甚至還在懷疑,軟體真的值這麼多錢嗎,服務也能賣嗎。

--

在一些複雜的分層架構裡面,我們通常可以把介面邏輯和商務邏輯分開,前者處理和驗證介面的互動,後者實現核心的商務程序。如果按照這樣的定義,現在應該是讓我們考察的重點進入商務邏輯的時候了。當然,在介面邏輯方面,除了PACS工作站上那些複雜的映像瀏覽和顯示功能之外,還有其他一些基於文本處理的工作站(比如登記工作站,醫生工作站等),它們也有很複雜的操作控制,以及資訊顯示和輸入的邏輯,從技術實現的角度來看,似乎跟其他行業應用區別不大。但是,如果要說到可用性設計,醫學領域還是會有一些非常不一樣的地方,比如對急診流程的支援,如何使用模版提高醫囑、病曆和報告編寫的效率,如何防止醫學錯誤等,這裡就暫時不深入了。其實,這些領域也可以挖掘出一些重要的設計模式和經驗。

另外,有些技術發燒友還會說,介面邏輯和商務邏輯之間還可以有一個介面層,作為facade用來實現商務服務的封裝。這層牛角尖我們就不必鑽了,真正需要用到的時候再去考慮吧。

商務邏輯是資訊系統的核心價值所在,但在我們看來,似乎只是系統需求的一個直接映射,沒有太多技術含量。其實,這隻是因為人們已經研究出了各種成熟的方法來實現它們。有些方法太過於成熟,以致於我們都感覺不到它們也可以總結為模式了。

一般來說,對於小型的系統,很多商務邏輯在預存程序裡面實現都已經綽綽有餘了,以致於它們看起來似乎沒有太多技術含量,只不過是一些經過定製的資料庫管理系統。我曾經看到某個放射科自己開發了一個基於Access的報告系統,它們自己建立一些表單和查詢(Access的術語,相當於帶上使用者介面的預存程序),甚至還通過檔案分享權限設定的方式實現了分布式,於是也成就了某些人的博士論文或者進階職稱。

稍微大一點的系統,有些商務邏輯就被放到應用程式的代碼裡面,並且出現了商務邏輯和資料訪問邏輯的區分(後者主要由預存程序來完成),並美其名曰多層架構。事實上,當你深入考察其中的代碼的時候,這種區分並不明顯,商務邏輯還是散落在代碼和預存程序裡面。對於這一點,有些人(比如一些常駐醫院的客戶化工程師)認為放在預存程序中的邏輯修改起來很容易,為客戶化提供了方便;有些人(比如一些專案管理規範和軟體工程過程的忠實信徒)則認為預存程序的指令碼難以進行管理,是潛在的trouble maker;有些人(比如資料庫專家)則認為預存程序的存在增加了系統對資料庫的依賴,不利於資料庫的移植;有些人(比如編譯語言的愛好者)則堅信預存程序一定可以極大地提升資料訪問效能。眾口難調啊。在那些熱烈而吵雜的爭論中,架構師必須做出理性的選擇。

再大一點的系統,作為中介層的商務邏輯也許需要依賴於更加重量級的實現了。90年代,微軟主打的資訊系統架構叫做Windows DNA,中介層主要依賴於COM+。現在,包括DCOM在內的各種分布式技術已經被統一到WCF裡面,WCF Service/WAS則取代了COM+/MTS,成為了.NET時代的對象容器。不管是那種容器,它的功能都是類似的,即為商務邏輯實現提供一些所謂企業級的服務品質,比如安全性、事務、訊息、會話、單點登入等。當然,按照微軟的風格,這些基礎設施都是在不同的產品中實現的,它們有個統一的總稱,叫做.NET企業伺服器。

更大一點的系統,尤其是跨部門或者跨機構的系統,.NET企業伺服器中的Biztalk Server就可以排上用場了。我們可以通過可視化的工具,在Biztalk上定義一些粗粒度的跨部門/機構的商務程序(當然,首先我們通常會理想化地按照SOA的風格,要求各個部門或者機構的系統基於業務職責來進行的粗粒度封裝)。用醫學行業習慣的術語,Biztalk就是一個介面引擎,或者說是一個整合平台,其中還包含了HL7套件,用以實現醫學領域的公司專屬應用程式整合。其實,醫學行業還有很多其他的介面引擎,有些甚至還是專門為醫學領域定製的。不過在國內,包括Biztalk在內的這些大型介面引擎應用得並不廣泛,大部分的醫院裡,資訊化的程度似乎還沒有達到可以大規模應用中介軟體的時候。很多醫院系統的整合還是停留在簡單的資訊轉換和文檔共用的層面上,通常都是由客戶化工程師直接修改代碼來直接存取第三方資料庫;更先進一點的則是使用一些小型的介面引擎,與第三方系統進行基於HL7和DICOM的標準化通訊,整合的工作可以通過配置而不是直接修改代碼來實現,這種應用目前大都出現在標準化遵從做得比較好的放射領域。

在傳統的企業級資訊系統中,很多人會把整合分為資訊/Data Integration和業務/工作流程整合兩個階段,前者相對比較簡單,後者就有點BPM或者BPR的味道。事實上,據我目前所瞭解到的情況看來,二者在技術實現上並沒有太大的差別,為了實現靈活的配置,兩者都可以依賴於構建在工作流程引擎基礎上的路由機制(隨著工作流程技術的普及,有些複雜的業務系統內部也會使用工作流程引擎來實現商務程序定製)。可能唯一不同的是,Data Integration更多地關注複雜資料格式之間的轉換,工作流程整合則需要更多地考慮補償/重試等複雜的工作流程模型。然而,為了在分布式的資料流中保證資料的可靠傳輸,我們不可能中過多地使用傳統的事務模型,那麼補償/重試等機制同樣是必要的。不管怎麼樣,整合和互通性已經被越來越多的認為是醫學資訊系統的核心技術之一。

關於醫學整合方面的一些模式,前面的文章已經進行了大量的敘述,這裡就不再重複了。如果還有什麼值得強調的,那就是《企業整合模式》裡面的一大堆東西,以及IHE Technical Framework了。後者為醫學整合提供的至今為止最好的業務模型描述。其實,不管是IHE還是HL7和DICOM的文檔,都隱含了大量的業務層面的描述,它們不光可以作為整合服務工程師的工作手冊,還可以作為醫學資訊系統需求開發和系統設計的標準化基礎。

--

終於,我們走到了資訊系統軟體的最後端,資料和資料訪問層了。

很多人會認為這一層的實現技術,似乎是最沒有醫學行業特徵的一部分。因為不管那個行業領域的業務實體,最終都可以表達成關聯式模式,或者物件導向模型,然後進行儲存和查詢。這一層中的設計模式,不管是為了支援擴充性,還是為了實現更好的效能,都跟其他行業領域的模式大同小異。不過,這些模式應用的關鍵,還是在於對醫學業務的理解。我曾經看到有人在架構放射裝置的控制台軟體(由於需要強大的映像運算,這種控制軟體一般運行在台式機而不是嵌入式系統上)的時候,竟然做出了在資料訪問層中使用某種便於資料庫移植的設計(即支援今天用SQLServer,明天用Oracle)。

當然,也有一些把其他行業的模式應用到醫學領域的正面例子。比如,要提供一個方案來讓系統平穩度過醫院裡周期性的業務流量高峰。毫無疑問,從硬體投資方面來解決顯然是一種巨大的浪費,常用的資料庫效能調優方案裡面也找不到什麼自適應的策略,那麼使用訊息佇列和非同步處理也許是唯一的方式。再如,要提供一個方案來支援客戶化階段可以方便地增加欄位,而不需要修改和重新編譯代碼。這個實現的方式也很多,歸納起來主要是兩種策略,要麼運行時動態增加列,要麼把列訪問轉換成行訪問。當然,後者可能更加適合於基於ORM的資料訪問層。不管怎麼樣,這往往都是一個從資料庫、資料訪問直到使用者介面的跨層的綜合性方案,配合使用者介面上的一些資料繫結策略,則更加如虎添翼。

事實上,後端系統的一些常見的設計目標,比如可靠性、效能和伸縮性、災難備份和恢複,很大一部分是依靠硬體系統的選型來實現的,常見的一些術語有Web Farm、雙機熱備、負載平衡、RAID、NAS、SAN、光碟片塔、磁帶庫等等。在軟體設計方面通常只需要注意一點,那就是伸縮性。在傳統的多視圖架構中,這方面的設計通常是通過進程視圖或者運行視圖中的線程和進程的規劃來體現。要使得系統具有scale-out的能力,我們在設計那些需要支援高輸送量的後台服務的時候,一個常見的原則是根據業務處理的步驟來劃分線程和進程,不同的步驟之間通過排隊機制來實現非同步呼叫,而永遠不要根據請求來劃分線程和進程;更好的實踐則是充分利用線程池來減少進程建立和銷毀的過程對系統資源的損耗。對於需要支援雙機熱備的業務處理,通常只能用進程而不是線程來作為宿主,並且把相關的狀態儲存到共用儲存,比如RAID中。

--

最後,我還是想引用《特定領域應用程式框架:行業的架構體系》一書中的一段話作為總結。這本書關於醫學行業的介紹很少,只有一個所謂的“插頁”,而且這段話裡面提到的技術也許看起來有點過時,但是在我看來之所以可以作為一個總結,是因為它跟架構有關。

架構這個東西,也許是現在軟體行業最重要和最流行的架構模式之一。跟傳統的被比喻成積木或者預製板的組件和類庫所不同的是,架構提供的是一個有地基,有梁有柱的半成品,甚至在這個半成品裡面連一些常用的牆和屋頂都幫你預留好了,於是可以更大程度上的提高產品甚至產品線的開發效率。當然,唯一不變的還是軟體行業裡面強調得最多的,即重用。只不過組件和類庫關注的是功能和代碼的重用,架構則是關注邏輯和設計的重用。因此,面向特定行業的應用程式框架中的體現的設計要點,更能代表這個行業的軟體設計中的最典型和最常用的模式和經驗。

通常,一個架構的架構是可以分為多個緯度的,比如從前端到後端,即技術的緯度,或者針對不同的使用者,即應用的緯度,或者針對不同的關鍵品質屬性,即品質的緯度。下面引用的這段話,應該是在技術的緯度上展開的。

“面向訊息的架構支援應用伺服器(或資料庫)端的訊息定製和交換,它可以使用對象請求代理技術(如CORBA或ActiveX)來傳送訊息。面向服務的架構支援醫學應用服務的開發,這些服務可以充分利用對象請求代理體繫結構和現有的分散式運算服務工具。可視整合架構重點處理案頭的自動化。這些架構隨著市場的變化和技術的進步而不斷地發展變化。”

補充一下,這裡的三個架構,面向訊息架構,面向服務架構和可視整合架構,分別被作者認為是適用於後端,中介層和前端的架構。正如作者所預言的那樣,在今天看來,用來構建這些架構的技術已經得到長足的發展,正如前文所述。

--

回顧一下,從醫學整合的故事開篇到現在,也寫了不少東西了。在這些不著邊際的文字中,真正關於整合的並不多,因為一些進行中的工作,是絕對不可能在這裡說的。其實這裡的自言自語,主要目的還是為了總結和整理一下自己的思路,尤其是對醫學行業軟體開發的理解。畢竟這個行業領域太大了,目前有機會接觸到的又太有限,加上自己記性比較差,生怕某些個細分領域幾年沒碰就忘得一乾二淨了。於是,能夠積累下來的,有多少就算多少吧。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.