java与模式chp17.pdf
《java与模式chp17.pdf》由会员分享,可在线阅读,更多相关《java与模式chp17.pdf(15页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Java 与模式作者阎宏博士 电子工业出版社出版 第 17 章 专题:多例(Multiton)模式与多语言支持 作为对象的创建模式,多例模式中的多例类可有多个实例;而且多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。请读者在阅读本章之前,先阅读本书的“单例模式”一章。17.1 引 言 一个真实的项目 这是一个真实的、面向全球消费者的华尔街金融网站项目的一部分。按照项目计划书,这个网站系统是要由数据库驱动的,并且要支持十九种不同的语言;而且在将来支持更多的语言。消费者在登录到系统上时可以选择自己所需要的语言,系统则根据用户的选择将网站的静态文字和动态文字全部转换为用户所选择的语言。经
2、过讨论,设计师们同意对静态文字和动态文字采取不同的解决方案:(1)把所有的网页交给翻译公司对上面的静态文字进行翻译,(2)而网页上面的动态内容则需要程序解决。在进行了研究后,设计师们发现,他们需要解决的动态文字的“翻译”问题,实际上是将数据库中的一些静态或者半静态的数据进行“翻译”。就是一个典型的数据表,如下表所示。货币代码 货币名称 货币尾数 USD America(United States of America),Dollars 2 CNY China,Yuan Renminbi 2 EUR France,Euro 2 JPY Japan,Yen 0 货币代码永远是上面所看到的英文代码,
3、但是货币名称应当根据用户所选择的语言不同而不同。比如对中文读者就应当翻译成为下面的表,如下表所示。货币代码 货币名称 货币尾数 USD 美国(美利坚合众国),美元 2 Java 与模式 268CNY 中国,人民币元 2 EUR 法国,欧元 2 JPY 日本,日元 0 这样的表会在网页上作为下拉菜单出现,用户看到的是货币名称,而系统内部使用的是货币代码。国际化解决方案 这样的问题就是国际化的问题,所谓国际化就是 Internationalization,简称 i18n(请参见本章最后的问答题)。设计师所采取的实际方案是分层方案,也就是 MVC 模式。MVC 模式将系统分为三个层次,即模型(Mod
4、el)、视图(View)、控制器(Control)。国际化是视图部分的问题,因此,应当在视图部分得到解决。MVC 模式的示意图如下所示。换言之,系统的内核可以是纯英文的。在内核外部增加一个壳层负责语言翻译工作。请见下面的英文内核和翻译壳层的概念图。所谓内核就是系统的模型,而翻译壳层便是视图的一部分。对多语言的支持属于视图功能,因此,不应当在内核解决,而应当在视图解决。这就是设计师们达成的总体方案。第 17 章 多例(Multiton)模式与多语言支持 26917.2 多 态 模 式 多例模式的特点 所谓的多例模式(Multiton Pattern),实际上就是单例模式的自然推广。作为对象的创建
5、模式,多例模式或多例类有以下的特点:(1)多例类可有多个实例。(2)多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。单例类一般情况下最多只可以有一个实例,请见下面的单例类结构图。但是单例模式的精神是允许有限个实例,并不是仅允许一个实例。这种最多允许有限多个实例,并向整个 JVM 提供自己实例的类叫做多例类(Multiton),这种模式叫做多例模式(Multiton Pattern),请参见下面的多例类结构图。本章就需要用多例模式来实现资源对象,需要构造出能提供有限个实例、每个实例有各不相同的属性(即 Locale 代码)的代码。有上限多例类 一个实例数目有上限的多例类已经把实例的上
6、限当做逻辑的一部分,并建造到了多例Java 与模式 270类的内部,这种多例模式叫做有上限多例模式。比如每一麻将牌局都需要两个色子,因此色子就应当是双态类。这里就以这个系统为例,说明多例模式的结构。色子的类图如下所示。下面就是多例类 Die(色子)的源代码。代码清单 3:多例类的源代码 package com.javapatterns.multilingual.dice;import java.util.Random;import java.util.Date;public class Die private static Die die1=new Die();private static D
7、ie die2=new Die();/*私有的构造子保证外界无法 *直接将此类实例化 */private Die()/*工厂方法 */public static Die getInstance(int whichOne)if(whichOne=1)return die1;else return die2;第 17 章 多例(Multiton)模式与多语言支持 271 /*掷色子,返还一个在 16 之间的 *随机数 */public synchronized int dice()Date d=new Date();Random r=new Random(d.getTime();int value
8、=r.nextInt();value=Math.abs(value);value=value%6;value+=1;return value;在多例类 Die 中,使用了饿汉方式创建了两个 Die 的实例。根据静态工厂方法的参数,工厂方法返还两个事例中的一个。Die 对象的 die()方法代表掷色子,这个方法会返还一个在 16 之间的随机数,相当于色子的点数。代码清单 4:客户端的源代码 package com.javapatterns.multilingual.dice;public class Client private static Die die1,die2;public stati
9、c void main(String args)die1=Die.getInstance(1);die2=Die.getInstance(2);die1.dice();die2.dice();由于有上限的多例类对实例的数目有上限,因此有上限的多例类在这个上限等于 1 时,多例类就回到了单例类。因此,多例类是单例类的推广,而单例类是多例类的特殊情况。一个有上限的多例类可以使用静态变量存储所有的实例,特别是在实例数目不多的时候,可以使用一个个的静态变量存储一个个的实例。在数目较多的时候,就需要使用静态聚集储存这些事例。无上限多例模式 多例类的实例数目并不需要有上限CAMP02,实例数目没有上限的多
10、例模式就叫做无上限多例模式。由于没有上限的多例类对实例的数目是没有限制的,因此,虽然这种多例模式是单例Java 与模式 272模式的推广,但是这种多例类并不一定能够回到单例类。由于事先不知道要创建多少个实例,因此,必然是使用聚集管理所有的实例。本章要讨论的多语言支持方案就需要应用到多例模式,关于没有上限的多例模式的实现可以参见下面的讨论。没有上限的多例模式(左)和有上限的多例模式(右)的类图如下所示。其中 N 就是实例数目的上限。有状态的和没有状态的多例类 如同单例类可以分成有状态的和没有状态的两种一样,多例类也可以分成有状态的和没有状态的两种。多例对象的状态如果是可以在加载后改变的,那么这种
11、多例对象叫做可变多例对象(Mutable Singleton);如果多例对象的状态在加载后就不可以改变,那么这种多例对象叫做不变多例对象(Immutable Singleton)。显然不变多例类的情形较为简单,而可变单例类的情形较为复杂。如果一个系统是建立在诸如 EJB 和 RMI 等分散技术之上的,那么多例类有可能会出现数个实例,因此,在这种情况下除非提供有效的协调机制,不然最好不要使用有状态的和可变的单例类,以避免出现状态不自恰的情况。读者可以参考本书的“单例(Singleton)模式”一章中的相关讨论。17.3 多语言项目的设计 由于熟悉了多例模式,系统的设计实际上并不复杂。语言代码 下
12、表就是几个常见的语言代码,如表所示。语 言 代 码 说 明 de German 第 17 章 多例(Multiton)模式与多语言支持 273en English fr French ja Japanese jw Javanese ko Korean zh Chinese 地区代码 下表就是几个常见的地区代码,如表所示。地 区 代 码 说 明 CN China DE Germany FR France IN India US United States Locale 代码 一个 Locale 代码由语言代码和地区代码组合而成,如下表所示。语 言 代 码 地 区 代 码 Locale 代码 说
13、明 en US en_US 美国英语 en GB en_GB 英国英语 fr FR fr_FR 法国法语 fr CA fr_CA 加拿大法语 de DE de_DE 德国德语 zh CH zh_CH 简体汉语 Resource 文件及其命名规范 一个 Resource 文件是一个简单的文本文件。一个 Resource 文件的名字是由一个短文件名和文件的扩展名 properties 组成的,而 Resource 文件的短文件名则是 Java 程序在调用此文件时使用的文件名。一个 Resource 文件和一个普通的 properties 文件并无本质区别,但 Java 语言对两者的支持是有区别的。
14、java.util.Properties 类不支持多语言,而 java.util.ResourceBundle 类则支持多语言。当 Locale 代码是 en_US 时,Resource 文件的文件名应当是短文件名加上 Locale 代码,就是 en_US。当 Locale 代码是 zh_CH时,Resource 文件的文件名应当是短文件名加上 LocaleJava 与模式 274代码,就是 zh_CH。怎样使用 Locale 对象和 ResourceBundle 对象 那么怎样使用 ResourceBundle 读取一个 Resource 文件呢?下面就是一个例子。代码清单 4:怎样使用 L
15、ocale 对象和 ResourceBundle 对象 Locale locale=new Locale(fr,FR);ResourceBundle res=ResourceBundle.getBundle(shortname,locale);在上面的例子里面,res 对象会加载一个名为 shortname_fr_FR.properties 的 Resource 文件。系统的设计 下图所示给出系统的结构图。其中 LingualResourceTester 是一个示意性的客户端类,而 LingualResource 是一个多例类。下面就是这个多例类的源代码。代码清单 5:多例类 LingualR
16、esource 的源代码 package com.javapatterns.multilingual;import java.util.HashMap;import java.util.Locale;import java.util.ResourceBundle;public class LingualResource 第 17 章 多例(Multiton)模式与多语言支持 275 private String language=en;private String region=US;private String localeCode=en_US;private static final St
17、ring FILE_NAME=res;private static HashMap instances=new HashMap(19);private Locale locale=null;private ResourceBundle resourceBundle=null;private LingualResource lnkLingualResource;/*私有的构造子保证外界无法直接将此类实例化 */private LingualResource(String language,String region)this.localeCode=language;this.region=reg
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 模式 chp17
限制150内