Java模式设计之多态模式与多语言支持

上传人:dfg****19 文档编号:172522076 上传时间:2022-12-05 格式:DOC 页数:42 大小:90.50KB
收藏 版权申诉 举报 下载
Java模式设计之多态模式与多语言支持_第1页
第1页 / 共42页
Java模式设计之多态模式与多语言支持_第2页
第2页 / 共42页
Java模式设计之多态模式与多语言支持_第3页
第3页 / 共42页
资源描述:

《Java模式设计之多态模式与多语言支持》由会员分享,可在线阅读,更多相关《Java模式设计之多态模式与多语言支持(42页珍藏版)》请在装配图网上搜索。

1、Java模式设计之多态模式与多语言支持作为对象的创建模式,多态模式中的多态类可有多个实例;而且多态类必须自己创建、管理自己的实例,并向外界提供自己的实例。读者在阅读本文的时候,可以参考阅读笔者的Java与模式一书(刚由电子工业出版社出版)中的相关章节。引言 一个真实的项目这是一个真实的、面向全球消费者的华尔街金融网站项目的一部份。按照项目计划书,这个网站系统是要由数据库驱动的,并且要支持十九种不同的语言;而且在将来支持更多的语言。消费者在登录到系统上时可以选择自己所需要的语言,系统则根据用户的选择将网站的静态文字和动态文字全部转换为用户所选择的语言。经过讨论,设计师们同意对静态文字和动态文字采

2、取不同的解决方案:把所有的网页交给翻译公司对上面的静态文字进行翻译, 而网页上面的动态内容则需要程序解决。在进行了研究后,设计师们发现,他们需要解决的动态文字的“翻译”问题,实际上是将数据库中的一些静态或者半静态的数据进行“翻译”。下面就是一个典型的数据表:货币代码货币名称货币尾数USDAmerica (United States of America), Dollars2CNYChina, Yuan Renminbi2EURFrance, Euro2JPYJapan, Yen0代码清单1、为英文用户的准备的货币列表。真的不掉线吗?、?货币代码永远是上面所看到的英文代码,但是货币名称应当根据用

3、户所选择的语言不同而不同。比如对中文读者就应当翻译成为下面的表:货币代码货币名称货币尾数USD美国 (美利坚合众国), 美元2CNY中国,人民币元2EUR法国, 欧元2JPY日本, 日元0代码清单2、为中文用户准备的货币列表。这样的表会在网页上作为下拉菜单出现,用户看到的是货币名称,而系统内部使用的是货币代码。国际化解决方案这样的问题就是国际化的问题,所谓国际化就是Internationalization,简称作i18n(请参见本章最后的问答题)。设计师所采取的实际方案是分层方案,也就是MVC模式。MVC模式将系统分为三个层次,也就是模型(Model)、视图(View)、控制器(Control

4、)三个部份。国际化是视图部份的问题,因此应当在视图部份得到解决。图1、MVC模式的示意图。真的不掉线吗?、?换言之,系统的内核可以是纯英文的;在内核外部增加一个壳层负责语言翻译工作。请见下面的概念图:图2、英文内核和翻译壳层的概念图。所谓内核就是系统的模型,而翻译壳层便是视图的一部份。对多语言的支持属于视图功能,因此不应当在内核解决,而应当在视图解决。这就是设计师们达成的总体方案。多态模式 多态模式的特点所谓的多态模式(Multiton Pattern),实际上就是单态模式的自然推广。作为对象的创建模式,多态模式或多态类有以下的特点:多态类可有多个实例; 多态类必须自己创建、管理自己的实例,并

5、向外界提供自己的实例。单态类一般情况下最多只可以有一个实例,请见下面的结构图:图3、单态类的结构图。但是单态模式的精神是允许有限个实例,并不是仅允许一个实例;这种最多只允许有限多个实例,并向整个JVM提供自己实例的类叫做多态类(Multiton),这种模式叫做多态模式(Multiton Pattern),请参见下面的结构图。图4、多态类的结构图。真的不掉线吗?、?本章就需要用多态模式来实现资源对象,需要构造出能提供有限个实例,每个实例有各不相同的属性(即Locale代码)。有上限多态类一个实例数目有上限的多态类已经把实例的上限当作逻辑的一部份建造到了多态类的内部;这种多态模式叫做有上限多态模式

6、。比如每一麻将牌局都需要两个色子,因此色子就应当是双态类。这里就以这个系统为例,说明多态模式的结构。图5、色子的类图。下面就是多态类Die(色子)的源代码:package com.javapatterns.multilingual.dice;import java.util.Random;import java.util.Date;public class Dieprivate static Die die1 = new Die();private static Die die2 = new Die(); /*私有的构造子保证外界无法*直接将此类实例化真的不掉线吗?、?*/private Di

7、e() /*工厂方法*/public static Die getInstance(int whichOne)if (whichOne = 1)return die1;elsereturn die2; /*掷色子,返还一个在1到6之间的*随机数。*/public synchronized int dice()Date d = new Date();Random r = new Random( d.getTime() );int value = r.nextInt();value = Math.abs(value);真的不掉线吗?、?value = value % 6;value += 1;re

8、turn value; 代码清单3、多态类的源代码。在多态类Die中,使用了饿汉方式创建了两个Die的实例。根据静态工厂方法的参数,工厂方法返还两个事例中的一个。Die对象的dice()方法代表掷色子,这个方法会返还一个在1到6之间的随机数,相当于色子的点数。package com.javapatterns.multilingual.dice;public class Clientprivate static Die die1, die2;public static void main(String args)die1 = Die.getInstance(1);die2 = Die.getIn

9、stance(2);die1.dice();die2.dice(); 代码清单4、客户端的源代码。由于有上限的多态类对实例的数目有上限,因此有上限的多态类在这个上限等于1时,多态类就回到了单态类。因此多态类是单态类的推广,而单态类是多态类的特殊情况。一个有上限的多态类可以使用静态变量储存所有的实例;特别是在实例数目不多的时候,可以使用一个个的静态变量储存一个个的实例。在数目较多的时候,就需要使用静态聚集储存这些事例。无上限多态模式多态类的实例数目并不需要有上轠CAMP02;实例数目没有上限的多态模式就叫做无上限多态模式。真的不掉线吗?、?由于没有上限的多态类对实例的数目是没有限制的,因此虽然这

10、种多态模式是单态模式的推广,但是这种多态类并不一定能够回到单态类。由于事先不知道要创建多少个实例,因此必然是使用聚集管理所有的实例。本章要讨论的多语言支持方案就需要应用到多态模式,关于没有上限的多态模式的实现可以参见下面的讨论。图6、没有上限的多态模式(左)和有上限的多态模式(右)的类图。其中N就是实例数目的上限。有状态的和没有状态的多态类如同单态类可以分成有状态的和没有状态的两种一样,多态类也可以分成有状态的和没有状态的两种。多态对象的状态如果是可以在加载后改变的,那么这种多态对象叫做可变多态对象(Mutable Singleton);如果多态对象的状态在加载后就不可以改变,那么这种多态对象

11、叫做不变多态对象(Immutable Singleton)。显然不变多态类的情形较为简单,而可变单态类的情形较为复杂。如果一个系统是建立在诸如EJB和RMI等分散技术之上的,那么多态类有可能会出现数个实例;因此在这种情况下除非提供有效的协调机制,不然最好不要使用有状态的和可变的单态类,以避免出现状态不自恰的情况。读者可以参考本书的“单态(Singleton)模式”一章中的相关讨论。多语言项目的设计由于熟悉了多态模式,系统的设计实际上并不复杂。真的不掉线吗?、?语言代码下面就是几个常见的语言代码:语言代码说明de German en English fr French ja Japanese j

12、w Javanese ko Korean zh Chinese 地区代码下面就是几个常见的地区代码:地区代码说明CN China DE Germany FR France IN India 真的不掉线吗?、?US United States Locale代码一个 Locale 代码由语言代码和地区代码组合而成,比如:语言代码地区代码Locale代码说明enUSen_US美国英语enGBen_GB英国英语frFRfr_FR法国法语frCAfr_CA加拿大法语deDEde_DE德国德语zhCHzh_CH简体汉语代码清单3、Locale代码、语言代码和地区代码。Resource文件及其命名规范一个R

13、esource文件是一个简单的文本文件。一个Resource文件的名字是由一个短文件名和文件的扩展名properties组成,而Resource文件的短文件名则是Java程序在调用此文件时使用的文件名。一个Resource文件和一个普通的properties文件并无本质区别,但Java语言对两者的支持是有区别的。java.util.Properties类不支持多语言,而java.util.ResourceBundle类则支持多语言。当Locale代码是en_US时,Resource文件的文件名应当是短文件名加上Locale代码,就是en_US。当Locale代码是zh_CH时,Resource

14、文件的文件名应当是短文件名加上Locale代码,就是zh_CH。怎样使用Locale对象和ResourceBundle对象。那么怎样使用 ResourceBundle 读取一个Resource文件呢?下面就是一个例子:真的不掉线吗?、?Locale locale = new Locale(fr,FR); ResourceBundle res = ResourceBundle.getBundle(shortname,locale); 代码清单4、怎样使用Locale对象和ResourceBundle对象。在上面的例子里面,res对象会加载一个名为shortname_fr_FR.propertie

15、s的Resource文件。系统的设计这里给出系统的结构图。其中LingualResourceTester是一个示意性的客户端类,而LingualResource是一个多态类。图7、多态类LingualResource和客户端类的类图结构。下面就是这个多态类的源代码:package com.javapatterns.multilingual;import java.util.HashMap;import java.util.Locale;import java.util.ResourceBundle;public class LingualResourceprivate String langu

16、age = en;private String region = US;private String localeCode = en_US;private static final String FILE_NAME = res;private static HashMap instances =真的不掉线吗?、?new HashMap(19);private Locale locale = null;private ResourceBundle resourceBundle = null;private LingualResource lnkLingualResource; /*私有的构造子保

17、证外界无法直接将此类实例化*/private LingualResource(String language, String region)this.localeCode = language;this.region = region;localeCode =makeLocaleCode(language , region);locale = new Locale(language, region);resourceBundle =ResourceBundle.getBundle(FILE_NAME, locale);instances.put( makeLocaleCode(language

18、, region) ,resourceBundle); /*私有的构造子保证外界无法直接将此类实例化*/private LingualResource()file:/do nothing /*真的不掉线吗?、?*工厂方法,返还一个具有指定的内部状态的实例*/public synchronized static LingualResourcegetInstance(String language, String region)if (instances.containsKey(makeLocaleCode(language , region )return (LingualResource) i

19、nstances.get(makeLocaleCode(language , region );elsereturn newLingualResource(language, region);public String getLocaleString(String code)return resourceBundle.getString(code);private static String makeLocaleCode(String language, String region)return language + _ + region;代码清单5、多态类LingualResource的源代

20、码。其中的makeLocaleCode()是一个辅助性的方法,在传入语言代码和地区代码时,此方法可以返回一个Locale代码。 这个多态类的构造子是私有的,因此不能用new关键字来实例化。所有的实例必须通过调用静态getInstance()方法来得到。在getInstance()方法被调用时,程序会首先检查传入的Locale代码是否已经在instances集合中存在;如果已经存在,即直接返回它所对应的LingualResource对象,否则就会首先创建一个这个Locale代码所对应的LingualResource对象,将之存入instances集合,并返回这个实例。 下面给出一个客户端的源代码

21、:真的不掉线吗?、?package com.javapatterns.multilingual;public class LingualResourceTesterpublic static void main(String args)LingualResource ling =LingualResource.getInstance(en , US);String usDollar = ling.getLocaleString(USD);System.out.println(USD= + usDollar);LingualResource lingZh =LingualResource.get

22、Instance(zh , CH);String usDollarZh = lingZh.getLocaleString(USD);System.out.println(USD= + usDollarZh);代码清单6、客户端类LingualResourceTester的源代码。如果用户是美国用户,那么在JSP网页中可以通过调用getLocaleString()方法得到相应的英文说明。比如:LingualResource ling = LingualResource.getInstance(en , US);String usDollar = ling.getLocaleString(USD)

23、; 就会返还US Dollar真的不掉线吗?、?相应地,如果用户是中国大陆的用户,那么在JSP网页中可以通过调用getLocaleString()方法得到相应的中文说明。比如,LingualResource ling = LingualResource.getInstance(zh , CH);String usDollar = ling.getLocaleString(USD); 就会返还美元Resource文件的内容 为美国英文准备的Resource文件res_en_US.properties的内容如下:USD=US DollarJPY=Japanese Yen代码清单7、Resource

24、文件res_en_US.properties的内容。 为简体中文准备的Resource文件res_zh_CH.properties的内容如下:USD=美元JPY=日元代码清单8、Resource文件res_zh_CH.properties的内容。 问答题真的不掉线吗?、?第一题、请问为什么Internationalization又简称作i18n?第二题、请给出一个根据语言代码和地区代码将数目字格式化的例子。第三题、请给出一个根据语言代码和地区代码将货币数目字格式化的例子。第四题、请给出一个根据语言代码和地区代码将百分比格式化的例子。问答题答案第一题答案、在英文字Internationaliza

25、tion中,第一个字母i和最后一个字母n之间有18个字母,因此Internationalization又简称作i18n。第二题答案、Java库java.text.NumberFormat类提供了对数目字格式的支持,下面给出的就是解答的类图:图8、对数目字格式支持的解答。程序的源代码如下:package com.javapatterns.multilingual.number;import java.util.Locale;import java.text.NumberFormat;public class NumberFormatTester static public void displa

26、yNumber(真的不掉线吗?、? Double amount, Locale currentLocale) NumberFormat formatter;String amountOut;formatter =NumberFormat.getNumberInstance(currentLocale);amountOut = formatter.format(amount);System.out.println(amountOut + + currentLocale.toString(); static public void main(String args) displayNumber(n

27、ew Double(1234567.89),new Locale(en, US);displayNumber(new Double(1234567.89),new Locale(de, DE);displayNumber(new Double(1234567.89),new Locale(fr, FR); 代码清单9、Resource文件res_zh_CH.properties的内容。在运行时,程序回打印出下面的结果:456,789% en_US456.789% de_DE真的不掉线吗?、?456 789% fr_FR代码清单10、Resource文件res_zh_CH.properties的

28、内容。 第三题答案、Java库java.text.NumberFormat类提供了对货币数目格式的支持。下面给出的就是解答的类图:图9、对货币数目格式支持的解答。程序的源代码如下:package com.javapatterns.multilingual.number;import java.util.Locale;import java.text.NumberFormat;public class CurrencyFormatTesterstatic public void displayCurrency(Double amount,Locale currentLocale) NumberF

29、ormat formatter; String amountOut; formatter =NumberFormat.getCurrencyInstance(currentLocale); amountOut = formatter.format(amount);真的不掉线吗?、? System.out.println(amountOut + + currentLocale.toString();static public void main(String args) displayCurrency(new Double(1234567.89), new Locale(en, US); dis

30、playCurrency(new Double(1234567.89), new Locale(de, DE); displayCurrency(new Double(1234567.89), new Locale(fr, FR);代码清单11、Resource文件res_zh_CH.properties的内容。在运行时,程序回打印出下面的结果:$1,234,567.89 en_US1.234.567,89 DM de_DE1 234 567,89 Ffr_FR代码清单12、Resource文件res_zh_CH.properties的内容。 第四题答案、Java库java.text.Numb

31、erFormat类提供了对百分比格式的支持,下面给出的就是解答的类图:图10、对百分比式支持的解答。程序的源代码如下:真的不掉线吗?、?package com.javapatterns.multilingual.number;import java.util.Locale;import java.text.NumberFormat;public class PercentFormatTesterstatic public void displayPercent(Double amount, Locale currentLocale) NumberFormat formatter; String

32、 amountOut; formatter =NumberFormat.getPercentInstance(currentLocale); amountOut = formatter.format(amount); System.out.println(amountOut + + currentLocale.toString();static public void main(String args) displayPercent(new Double(4567.89), new Locale(en, US); displayPercent(new Double(4567.89), new Locale(de, DE); displayPercent(new Double(4567.89),真的不掉线吗?、? new Locale(fr, FR);代码清单13、Resource文件res_zh_CH.properties的内容。在运行时,程序回打印出下面的结果:1,234,567.89 en_US 1.234.567,89 de_DE1 234 567,89 fr_FR真的不掉线吗?、?代码清单14、Resource文件res_zh_CH.properties的内容。(本章问答题第二、三、四题的解答参考了GREEN的相关例子,在这里我作了一些改动。) 真的不掉线吗?、?

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!