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. 总结 国际化支持是程序设计中不可获取的部分,如何更加方便、合理的加入国际化的支持是设计架构环节不可逃避的必然内容。本文在对国际化做出了简单介绍的同时,并对可能的实现原理给出了相应的阐述,希望能给各位带来些许帮助,减轻些痛苦。
欢迎转载,鄙视剽窃。