天天看點

淺談國際化

1. 什麼是國際化   國際化,即Internationalization,可以簡單表達為俗稱的I18N(首字母為I,末字母為N,中間有18個字元),代表着一個軟體或程式(以下簡稱“軟體”)具有可被多地方群體正常使用的能力。其中,“正常使用”意指軟體與群體互動時,界面等處呈現的語言符合當地的習俗,能夠被當地人群正常閱讀等。沒有國際化支援,一個開發的軟體就隻能現定于使用同樣語言的群體使用。例如,一個土著人開發的軟體,在中國恐怕是沒有人看得懂的。   一個軟體國際化的寬度,是要靠軟體自身實作的。就中國本地軟體而言,其國際化一般情況下隻支援中文和英文兩種。如果德國的朋友需要,那麼就必須在軟體中加入對德文的支援。 2. 為什麼要國際化   在國際化的意識進入業界之前,軟體的表現是固化到源代碼中的。這種方式直覺,簡單。但在需要多國語言支援的時候,就不得不把軟體從裡到外,前前後後更改一遍,并需要重新編譯、釋出對應版本。這無疑增加了軟體的維護成本,而且軟體越龐大,維護成本越高。   在國際化進入人們視野之後,軟體的設計開始逐漸将表現内容獨立抽取出來,形成了獨立的子產品。這種做法在極大的降低了軟體的維護成本的同時,也友善了程式開發時問題的定位,可謂是一舉兩得,甚至是多得。 3. 通用國際化方案   國際化方案大多通過鍵值對完成映射。例如,界面中“系統正在更新,請稍後...”的提示資訊可以通過鍵值對:[com.test.updating, "系統正在更新,請稍後..."]來映射。其中“com.test.updating”為鍵,提示資訊為值。程式在需要的時候根據鍵擷取對應值資訊,然後呈現給使用者。   鍵值對的存儲方式,目前大多數是以語言為機關,分檔案獨立存放。例如,英文版對應與一個國際化鍵值對檔案:i18n_enUS.xml,中文版對應于另一個國際化鍵值對檔案:i18n_zhCN.xml。兩個檔案通過共享一個鍵,而提供不同的翻譯。存儲檔案多采用xml檔案的形式。是以,上述兩個檔案可以簡單的由以下内容構成:   英文版,i18n_enUS.xml:

  ...
  <map key = "com.test.updating" value = "The system is updating, wait please..."/>
  ...
   中文版,i18n_zhCN.xml:
  ...
  <map key = "com.test.updating" value = "系統正在更新,請稍後..."/>
           

  當程式需要将此提示資訊呈現給使用者的時候,遍可以通過如下方式取出國際化内容:

  tip(open(語言環境是中文? "i18n_zhCN.xml": "i18n_enUS.xml").get("com.test.updating"));
           

4. 适用于Java EE的另一個國際方案   與前面介紹的通用國際化方案不同,本國際化方案在沿用鍵值對的前提下,更改檔案儲存方式為以JSON格式存放的Js檔案。其格式如下:   i18n.zh_CN.js:   var i18n = {"com.test.updating": "系統正在更新,請稍後..."}   i18n.en_US.js:   var i18n = {"com.test.updating": "The system is updating, wait please..."}   由此可見,此種鍵值對表達方式更為簡潔明了,而且通路方式更為簡單,如:   tip(i18n["com.test.updating"])。   相比而言,這種存儲方式更加适合于Java EE的html用戶端,因為它是JSON格式的,是以可以很容易的以原生js的方式被浏覽器解析,省去了文檔讀取和解析的過程。這種方案也正是個人所推薦的。但需要注意的是,此方案對于其他類型的應用可能并不合适。 5. 國際化的動态性   很多時候,國際化可能會涉及内容的動态性。如“使用者名:abc注冊失敗,已存在”的提示資訊需要在背景程式動态填充重複的使用者名。這個時候采取上述的國際化方式就已經不合适了。對于這種動态性,可以通過如下兩種方式解決:   1. 通過占位符動态填充   2. 國際化js檔案提供動态輸出功能   以下将分别對兩種方案的原理做出簡單介紹。   方案1:通過占位符動态填充:   這種方案将動态内容用特殊的字元串臨時代替,當确定動态部分的最終取值時,再使用最終取值進行替換。其中使用的特殊的臨時字元串稱之為“占位符”。例如:   {"com.test.DuplicateUserName": "使用者名:{name}注冊失敗,已經存在"}中"{name}"便是占位符,當程式運作到最後,确定重複的使用者名為"abc"時,通過執行字元串的替換操作,将"{name}"替換為"abc",也就變成了最終的提示資訊:“使用者名:abc注冊失敗,已經存在”。   方案2:國際化js檔案提供動态輸出功能   這種方案通常通過提供一個通用的國際化内容設定、擷取插件來完成。在擷取國際化内容時,通過函數方法的調用,根據傳入參數動态輸出内容。個人閑暇之餘已完成一個雛形,現無償貢獻給大家參考:http://download.csdn.net/detail/baozhang007/5534235   插件中i18n.$.get方法正是這種動态輸出功能的重點。根據傳入參數需要輸出什麼樣的字元串完全可以手動控制,而且非常靈活。相比方案1而言具有更強大的動态支援性。這也正是個人所推薦的。   插件使用方法:   1. 國際化鍵值對映射檔案單獨建立一個js檔案,并通過i18n.$.pack加入。這種以包為機關存儲的方式是為了便于子產品化管理   2. 頁面加入國際化支援檔案:i18n.js, i18n.子產品.js   3. 擷取國際化文本資訊時,通過i18n.$.get方法獲得,也可以通過i18n["包名"][鍵名]獲得。但第一種方式支援動态性。 6. 總結   國際化支援是程式設計中不可擷取的部分,如何更加友善、合理的加入國際化的支援是設計架構環節不可逃避的必然内容。本文在對國際化做出了簡單介紹的同時,并對可能的實作原理給出了相應的闡述,希望能給各位帶來些許幫助,減輕些痛苦。   

  歡迎轉載,鄙視剽竊。

繼續閱讀