可伸縮性是一種對軟件系統處理能力的設計指標,高可伸縮性代表一種彈性,在系統擴展過程中,能夠保證旺盛的生命力,通過很少的改動,就能實現整個系統處理能力的增長。
在系統設計的時候,充分地考慮系統的可伸縮性,一方面能夠極大地減少日后的維護開銷,并幫助決策者對于投資所能獲得的回報進行更加精準的估計;另一方面,高可伸縮性的系統往往會具有更好的容災能力,從而提供更好的用戶體驗。
WEB交互式系統的可伸縮性主要體現在兩個方面:
WEB交互式系統的主要應用包括:
本系列文章主要分為兩個主要部分對可伸縮性進行闡述,分別是平臺的可伸縮性和模塊的可伸縮性。本文是系列文章的第一篇,討論平臺的可伸縮性。
平臺的可伸縮性
WEB交互式系統對平臺的可伸縮性主要表現為:
我們先介紹一下WEB交互式系統的目標平臺的情況。
平臺分類
根據系統所在容器的差異,我們將平臺分為瀏覽器平臺和混合應用平臺兩大類。各分類的詳細說明見下文所述。
瀏覽器平臺
按引擎劃分
瀏覽器平臺,按照主流引擎可以劃分為以下幾類:
混合應用平臺
根據混合應用的宿主平臺的差異,我們將混合應用的目標平臺分為以下幾類:
宿主 |
說明 |
Android | Android系統的混合應用,瀏覽器引擎會自動適配至Webkit |
iOS | iOS系統的混合應用,瀏覽器引擎會自動適配至Webkit |
WinPhone | Windows Phone系統的混合應用,瀏覽器引擎會自動適配至Trident |
PC | 桌面應用,采用CEF做為容器,瀏覽器引擎會自動適配至Webkit |
平臺適配
AOP(Aspect-Oriented Programming):面向切面的編程范式,其核心思想是將橫切關注點從主關注點中分離出來,因此特定領域的問題代碼可以從標準業務邏輯中分離出來,從而使得主業務邏輯和領域性業務邏輯之間不會存在任何耦合性。
這里我們可以借鑒AOP思想來實現平臺的適配策略,結合不同的平臺實現邏輯,我們可以認為對于使用規范、標準來實現業務邏輯的部分為我們的主關注點,而不同平臺可以做為若干的切面關注點進行封裝,各平臺只需關注自己平臺下對標準的修正邏輯即可,因此可以通過增加、刪除平臺修正的切面邏輯來實現對不同平臺的適配。
實現時我們首先提取標準業務邏輯,然后各平臺根據實際情況實現對業務邏輯的修正:
根據此思路我們對比以下兩段代碼:
代碼一:目前常用的平臺適配方式
function doSomething(){ if(isTrident){ // TODO trident implement }else if(isWebkit){ // TODO webkit implement }else if(isGecko){ // TODO gecko implement }else if(isPresto){ // TODO presto implement }else{ // TODO w3c implement } } // 上層應用使用 doSomething(1,2,3);
此方式對所有平臺的修正邏輯均在主邏輯中實現,存在以下弊端:
代碼二:借鑒AOP思想的平臺適配方式
function doSomething(){ // TODO w3c/es implement } // 上層應用使用 doSomething(1,2,3);
針對Trident平臺適配的邏輯,比如 trident.js中
// trident implement doSomething = doSomething._$aop( function(_event){ // TODO trident implement }, function(_event){ // TODO trident implement } );
對比代碼一,我們可以發現借鑒AOP思想的接口適配方式分離了標準業務邏輯和平臺特有業務邏輯,是否增加平臺特有業務邏輯并不會影響主業務邏輯的執行,而對于平臺修正邏輯的切入則可以直接通過配置的方式靈活的進行增刪,因此我們可以從中得到以下好處:
實現舉例
NEJ框架借鑒AOP思想提供了配置式的平臺適配系統,對于這部分的詳細信息可參閱NEJ的《依賴管理系統》和《平臺適配系統》了解更為詳細的信息,以下僅舉例說明NEJ中適配的使用方式。
一個典型的適配控件結構如下圖所示:
這里的widget.js是控件業務邏輯實現文件,在此控件的實現中會依賴到存在平臺差異的API,其依賴代碼如下所示
NEJ.define([ 'util/event', '{platform}api.js' ],function(t,h,p){ // TODO });
這里對 {platform}api.js 的處理方式如下圖所示,這里的./相對于當前的代碼文件即widget.js文件所在的目錄
這里的api.js文件為需平他適配API的標準實現邏輯,而api.patch.js文件則利用NEJ.patch接口對各平臺做按需適配邏輯,同時打包時也根據NEJ.patch接口中對平臺的條件識別做按需輸出,由于api.patch.js文件最終會按需輸出,因此在此文件中除了使用NEJ.patch做平臺適配邏輯外,不允許包含其它業務邏輯。
// 此文件只能定義NEJ.patch不可執行其他業務邏輯 // 打包輸出時僅根據平臺配置輸出所需處理邏輯 // 實際情況看需求,可將平臺相關部分邏輯獨立到單獨的模塊中 NEJ.define([ './hack.js' ],function(h){ // 針對trident平臺的處理邏輯 NEJ.patch('TR',function(){ // TODO }); // 針對gecko平臺的處理邏輯 NEJ.patch('GR',[ './hack.firefox.js' ],function(fh){ // TODO }); // 針對IE6平臺的處理邏輯 NEJ.patch('TR==2.0',['./hack.ie6.js']); // 針對IE7-IE9的處理邏輯 NEJ.patch('3.0<=TR<=5.0',function(){ // TODO }); // 這里必須同hack.js文件的返回值一致 return h; });
最后我們只需要配置產品的目標平臺即可輸出平臺對應的適配,而不會存在其他平臺的額外影響:
<script src="/path/to/nej/define.js?p=wkgktd"></script> <script src="/path/to/nej/define.js?p=cef"></script>
平臺變更
通過以上實現舉例我們可以看到當平臺發生變更時我們可以快速進行擴展或縮減
平臺擴展
當有新平臺需要作為系統目標平臺時,我們只需要做以下工作:
系統對平臺配置部分增加新添的識別符,如
原平臺適配:<script src="http://www.vxbq.cn/uploadfile/cj/20140920//path/to/nej/define.js?p=wkgktd"></script>
新增平臺適配:<script src="http://www.vxbq.cn/uploadfile/cj/20140920//path/to/nej/define.js?p=wkgktdnxw"></script>
即可完成對平臺的擴展,而不會影響到原有的業務邏輯。
平臺縮減
當系統適配的目標平臺由于某種原因退出歷史舞臺時,系統也需要將該平臺的冗余代碼從系統中剔除,我們只需要做以下工作:
系統對平臺配置部分刪除要剔除的平臺標識,如:
原平臺適配:<script src="http://www.vxbq.cn/uploadfile/cj/20140920//path/to/nej/define.js?p=wkgktd"></script>
縮減后平臺適配:<script src="http://www.vxbq.cn/uploadfile/cj/20140920//path/to/nej/define.js?p=wk"></script>
即可完成對平臺的縮減,而無需修改任何業務邏輯。
以上即是有關平臺可擴展性的介紹。下一篇將闡述模塊的可擴展性,敬請期待!
本作品采用知識共享署名 4.0 國際許可協議進行許可。
上一篇 深入淺出交換類排序算法
下一篇 數字證書及CA的掃盲介紹