你的项目刚刚启动?是时候考虑Globalization了!
今天继续由SAP成都研究院非典型程序猿, 菜园子小哥王聪给大家带来分享。
关于这个很长的定语的由来,请参考这篇文章,里面有王聪的背景介绍,包括他种菜的特长:当我用UI5诊断工具时我用些什么。
秋天到了,娃娃们开学了,又是一个收获的季节。虽然过去的8月,成都雨水偏少,但是对于王聪来说这些都不是事,他的庄稼一样获得了丰收。有图为证:
下面是王聪的正文。
我身边的朋友中追求个性的人很多,但我最佩服的是我表弟小周。他的人生处处都把“酷”作为唯一的行事准则,甚至反映在了高考报考这种人生大事上。
“我要学最酷的专业。”
深知他个性的我明白这事挡不住,只能顺着。于是给他推荐长沙民政职业技术学院的殡仪学院,里面的专业随便说一个出来都是让人目瞪口呆。何止是酷,简直酷到口吐白沫!
他爸妈听了我的建议恨不得打死我,只有小周眼放金光,作势就要把志愿填了且不服从调剂。全家人一致决定剥夺我提出建议的权利,并通过各种威逼利诱、恐吓威胁终于把小周的殡仪梦想扼杀于摇篮之中。
可强权暴政镇压不住一颗红彤彤的向往个性的心,最终小周还是报考了一个极其冷门的专业——北外的豪萨语专业。
“先不说这个专业多冷门,就这个名字,说出来,酷不酷?”
“酷酷酷!”我连声附和。
可后来我才知道这真的是一门极其冷门极其古老的语言,甚至古老到了仍在大量使用象声词的程度。比如鸭子就叫“啊呱呱”(agwagwa),两只鸭子就叫“啊呱呱啊呱呱”。感叹这孩子真有个性之余,我也在内心暗暗替小周祈祷,毕业千万别去了当地的养鸭场工作。实在无法想象他用豪萨语骄傲地给客户介绍“我们公司年产50万只鸭子”会是怎样磅礴的景象。
今天的文章跟鸭子无关,我只想谈一谈语言。
文章目录
爱TA,就给TA足够的空间
拼接文本是把双刃剑!
也许……您硬编码了标点符号 囧
即便您的客户是冯绍峰,也不要随便把人家的名字倒过来写
小心使用大小写转换
语言的复杂性,远远不止如此
不要过度限制用户的输入
你真的了解搜索和排序吗?
好的注释是i18n文件的灵魂
据统计世界上已存在的语言多达5000多种,即便不考虑豪萨语这种冷门语言,被广泛使用的语言也有几十种。把温暖(chǎn pǐn)洒满人间是每一个程序员的梦想,可又不能指望每一个客户都使用英语,这时便产生了软件Globalization这一概念。
作为SAP九大Product Standards(产品标准)之一的Globalization,不单单是指文本的翻译,还包含支持多货币、支持各国相关法律、支持不同国家业务流程等要求。为了满足这一系列的标准,不但需要开发人员有过硬的业务知识,有时还需要花大把精力实现一些枯燥复杂的功能(比如为满足阿拉伯语,需要UI支持从右向左的排布)。
但是在产品的设计和开发初期,如果开发人员愿意花费一些精力去留心一些方面,那么就可以大大降低未来出现Globalization问题的概率。下面我们就列举SAP UI5开发的几个和Globalization相关的例子,特别感谢Ray Ding和Vicky Chen同学对文中部分内容的研究。
爱TA,就给TA足够的空间
在UX设计UI布局的初期,就应该将Globalization纳入考虑,而这时最容易引发的问题就是空间不够。一套布局在英文环境看上去美轮美奂,并不代表在其他语言环境中也有很好的用户体验,有时甚至会影响到可用性。比方说下面这个“添加”按钮,在英文环境下看起来还不错,但是切换到了德语就会让人完全看不懂。
大多数情况下,一个英文单词的长度是短于其他语言相同意义的单词。而我们大多数的产品都是以英语作为第一版语言进行开发的。当用户已经习惯了英语的布局之后,这时再因为引入其他语言而大幅度更改页面布局,将会是非常痛苦的事情。所以,请永远记得给文本足够的空间。
可是多大才算足够呢?幸运的是我们有一个工具叫做Text Space Calculator。它能够根据您提供的英文文本来推荐出一个能够满足90%以上情况的长度。感兴趣的同学可以看一下它的说明文档,也许您会发现它背后的逻辑非常简单粗暴,但是的确能够帮助到我们。同时它还有一个Bridge的版本,您可以在Bridge中搜索“UI text space calculator”然后把它添加进您的应用。
另外一个非常实用的工具就是Pseudo,它的基础就是上面介绍的Text Space Calculator。您可以通过它快速地发现潜在的文本截断问题,同时它还能够帮助我们发现UI上的硬编码以及拼接文本。
拼接文本是把双刃剑!
拼接文本是指在UI5项目里的i18n文件中将某些固定文本以参数的形式传入,并拼接在一起的方式。这样做的好处是可以在运行时动态的生成一些文本。类似的代码在我们的产品中屡见不鲜,可当我们开始考虑多语言的时候,可能会发现突然间,一切都玩不转了。
也许……您硬编码了标点符号 囧
一天,产品经理下达了任务:“我们把所有有效的产品都展示给用户吧!”于是,您可能就写下了这样的代码:
一切看起来这么完美,多语言的情况也加以考虑了,在英文环境中测试了一下,得到了想要的结果:Your active products: “apple” “orange” “banana”。但实际上,这种解决方案忽略了一个事实,就是双引号在不同的语言中看起来有可能是不同的。比如下图,是双引号在英语,汉语和德语三种语言中不同的表现形式:
与之类似的还有括号,句号等。虽然在有的场合下,有的朋友并不认为这是一个致命的问题,但是从Globalization的角度来讲,它确实不是一个完美的解决方案。
即便您的客户是冯绍峰,也不要随便把人家的名字倒过来写
在GitHub中随便翻一翻,就能看到很多诸如firstName + ” ” + lastName这样的代码。作为习惯姓氏放在最前面的国内读者,我们知道这样的写法是十分片面的,但是这样的问题在开发时经常会被忽视掉。类似的问题还有日期,永远不要让代码中出现类似下面这样将月,日,年的相对位置进行的硬编码:
month + “/” + day + “/” + year。
小心使用大小写转换
在很多的应用场景下我们会使用到大小写转换,比如字符串对比、字符串排序等,偶尔也会用在拼接文本中。而不恰当的使用大小写转换则会引起潜在的Globalization问题。下面我们通过一个例子加以说明。
假设我们现在有一个客户维护页面,用户可以创建或更改客户的基本信息,比如姓名,电话号码,邮箱等。页面上会对每个字段的格式加以校验,当校验不通过时则会对弹出类似这样的警告:“The field email does not match the format.”
我们当然可以给每一个字段都维护这样一条极其类似的警告,但这时“聪明”的我们发现在i18n文件中已经维护了各个字段的标签,所以我们是不是可以只维护一条警告,然后将这些标签通过参数传进去呢?想一想还真是有点小激动呢,于是说干就干。
作为严谨的工程师,我们当然考虑到了把字段标签传入Error Message的时候,要转换成小写,这样才符合英语的语法!可是却不知道这样却为日后引入Globalization埋下了隐患。并不是所有的语言都与英语有着相同的大小写规范,比方说在德语中任何名词在任何情况下都要保持首字母的大写,上面这段代码在德语环境下无疑成了画蛇添足。
语言的复杂性,远远不止如此
还是从一个案例开始,假设产品经理叫我们实现一个购物车,当用户之前添加的某种属性的某种商品被下架了之后,提醒用户商品不可用。
有了上面的种种教训,我们终于学会了要把文本中的标点以及顺序信息统统写入i18n文件,也不能随意更换大小写。所以我们想出了这样的提示信息:
这下总没问题了吧?翻译人员可以根据不同的语言调整参数{0}和{1}的位置,我们也不会主动修改参数的大小写。在英文环境中测试一下,“Sorry, the blue pen is not available. ”,完美。
但是后面我们还是再次栽在了Globalization上面,因为不是所有的语言都像英语这么简单。比方说这种简单粗暴的拼接在德语中是完全行不通的,感兴趣的同学可以通过下面这个介绍德语语法的wiki了解一下:
https://en.wikipedia.org/wiki/German_grammar
(Jerry旁白:我看了这个wiki,看不懂,烧脑,因此对本文作者能够以中英德三语在SAP Community上写博客表示非常佩服。当然,深受SAP成都同事爱戴的另一位老员工,林师傅,他的德语口语流利程度就不用多说了,去年Jerry和林师傅去德国一个小镇上买床垫,林师傅和销售小妹交谈了15分钟,我全程就听懂了一个单词:Tschuess 囧)
如果觉得wiki太难读懂了,那就对比一下下面四句话,会发现定冠词和形容词居然是一直在变的。
所以永远不要低估语言的复杂性,再回想一下“啊呱呱啊呱呱”,真的无法想象其他的语言到底是什么样的逻辑。所以在进行文本拼接的时候一定要慎重。
不要过度限制用户的输入
有些时候我们习惯对于用户的输入进行一定的限制,以保证数据的质量和一致性。但是限制要有度,比方说如果对于“名字”这个字段限制为仅接受大小写英文字母以及一些标点符号,那这样的限制在未来就很可能会出现问题。
你真的了解搜索和排序吗?
搜索和排序是两个极其常用的数据处理操作,而且往往都是在一个应用架构的设计初期就被纳入考虑。所以,如果我们能够在架构设计阶段就充分考虑一些潜在问题出现的可能性,那么将来很有可能就能避免收到一些Globalization的ticket。
搜索
关于字符串的搜索,我们比较常用的是“equals”和“contains”这两种策略。但其实这两种策略都应该基于不同的语言做出不同的反馈。举一个例子,德语中的“ö”同时可以表现为“oe”,所以如果用户想要搜索德国球星厄齐尔(可惜今年俄罗斯世界杯他和德国国家队整体一样状态低迷),无论输入是“Özil”还是“Oezil”,我们的搜索都应该命中到数据库中的同一条记录。幸运的是大多数数据库都支持这样的行为,只不过我们要记得去配置。
排序
“Apple”应当被排在“Banana”之前,因为“A”比“B”靠前。那如果我要将“Apple”、“Banana”、“安全”、“崩溃”四个文本在数据库中排序呢?你觉得正确的顺序是什么?我认为这个跟用户的使用语言是相关的。对于一个英文用户你把“安全”放在“Apple”和“Banana”中间是显然不合理的,但是对于某些中文用户他们又会觉得从拼音的角度就应该把“安全”放在那里啊。所以在数据库设计初期,应当尽量考虑到对于多语言排序的支持。
好的注释是i18n文件的灵魂
使用注释是一个良好的编程习惯,尤其是在i8n文件当中。请永远记得,当一个翻译人员在翻译您的i18n文件的时候,阅读注释是TA获取文本含义的唯一方式。一个不好的注释往往会对翻译人员造成困扰。比如如果没有注释,“Order”这个词可能有很多种翻译:
订单
顺序
命令
所以,在维护每一个i18n条目的时候,都请认真仔细地去写一条注释,这样有帮于避免未来的许多麻烦。在产品标准中对于i18n的注释有如下建议:
您在实际工作中,是否也才踩过一些和Globalization相关的坑呢?欢迎留言,说出您的故事。感谢阅读。
更多阅读
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
你的项目刚刚启动?是时候考虑Globalization了!的更多相关文章
- 【项目启动】 tomcat启动,项目无法启动,无法正常访问/项目可以启动,报错:java.lang.ClassNotFoundException: ContextLoaderListener
使用maven搭建项目(这个错误和是不是使用maven搭建项目没有关系),然后部署到tomcat中运行. 出现问题1: tomcat跑起来了,但是启动时间很短,没有报错,项目不能正常访问 项目启动时间 ...
- maven web 项目中启动报错 Java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
主要原因是maven项目里面的jar包吗,没有导入到项目中 maven web 项目中启动报错 Java.lang.ClassNotFoundException: org.springframewor ...
- 配置spring的监听器 让spring随项目的启动而启动
<!-- 配置spring的监听器 让spring随项目的启动而启动 --> <listener> <listener-class>org.springframew ...
- 同一个tomcat部署多个项目导致启动失败
内容描述在同一个tomcat部署多个打包成war包的项目导致启动失败,报错如下: 报错信息Error starting ApplicationContext. To display the condi ...
- zw字王《中华大字库》2018版升级项目正式启动
zw字王<中华大字库>2018版升级项目正式启动 https://www.cnblogs.com/ziwang/p/9500537.html 这次升级是和字库协会一起合作,首批推出的字体, ...
- CentOS磁盘用完的解决办法,以及Tomcat的server.xml里无引用,但是项目仍启动的问题
这是我2018年的第一篇博客...人真是懒了啊...最近在写微信小程序,觉得小程序做的也... 好了不吐槽了,言归正传 前言: 由于我之前不是买了个三年的香港服务器么 , 之前广州2的服务器我就没有续 ...
- django项目创建启动 ORM操作
. HTTP协议消息的格式: . 请求(request) 请求方法 路径 HTTP/1.1\r\n k1:v1\r\n ...\r\n \r\n 请求体 <-- 可以有,可以没有 . 响应(re ...
- 使用IntelliJ IDEA新建maven的javaWeb项目部署,启动访问index,jsp页面
对于用惯了eclipse的人,idea其实还挺不一样的,也是摸索了很久,看了好多博客,这里就记录一下,以后肯定经常用!,不过使用熟练了,功能确实非常强大,真的牛! 1 新建maven项目,配置好目录结 ...
- web项目tomcat启动url自定义(去掉项目名)
通常,使用maven构建web项目,启动时默认的访问路径: http://ip:port/项目名 很多时候我们不喜欢这样 访问,我们希望下面的访问方式: http://ip:port 如果是本地的to ...
随机推荐
- How to run Media SDK samples on Skylake【转载】
In the last few days, we have seen lot of concern for using Intel® Media 2016 on 6th generation Inte ...
- OpenCV2.4.13+VS2012开发环境配置
1.下载和安装OpenCV SDK 在OpenCV官网的下载页面: http://opencv.org/downloads.html 找到对应OpenCV for Windows版本下载.目前(2 ...
- [Selenium] 操作 警告框、提示框、确认框
以如下页面为例: http://sislands.com/coin70/week1/dialogbox.htm 示例代码: pachage com.learningselenium.normalweb ...
- 一梦浮生2012 IOS高级进阶目录
一梦浮生2012 精通iphone的UI开发,能熟练操作复杂表视图,熟练使用图层技术, 可以自定义UI控件,使用类别扩展系统控件功能; 擅长通讯技术,熟悉各种通信协议,精通xml, json, 二进制 ...
- saltstack自动化运维快速入门
saltstack自动化运维快速入门 关于saltstack 这个软件是干啥的 我这里就不介绍了 只是简单的说下是干啥的 网上的说法是 它是func的强化版本+ puppet的精简版 关于puppet ...
- MySQL中的RAND()函数使用详解
转自:https://www.jb51.net/article/66697.htm MySQL RAND()函数调用可以在0和1之间产生一个随机数: ? 1 2 3 4 5 6 7 mysql> ...
- 详解Supervisor进程守护监控
Supervisor在百度百科上给的定义是超级用户,监管员.Supervisor是一个进程管理工具,当进程中断的时候Supervisor能自动重新启动它.可以运行在各种类unix的机器上,superv ...
- 探究final在java中的作用
目录 一. final修饰变量 1. 基础: final修饰基本数据类型变量和引用数据类型变量. 2. 进阶: 被final修饰的常量在编译阶段会被放入常量池中 3. 探索: 为什么局部/匿名内部类在 ...
- bzoj 4407: 于神之怒加强版【莫比乌斯反演+线性筛】
看着就像反演,所以先推式子(默认n<m): \[ \sum_{d=1}^{n}d^k\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==d] \] \[ =\sum_{d=1} ...
- spring简介、容器、IOC
对IOC的理解: 在平时的java应用开发中,我们要实现某一个功能或者说是完成某个业务逻辑时至少需要两个或以上的对象来协作完成,在没有使用Spring的时候,每个对象在需要使用他的合作对象时,自己均要 ...