版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、-. zJava模式設(shè)計(jì)之多態(tài)模式與多語(yǔ)言支持作為對(duì)象的創(chuàng)立模式,多態(tài)模式中的多態(tài)類可有多個(gè)實(shí)例;而且多態(tài)類必須自己創(chuàng)立、管理自己的實(shí)例,并向外界提供自己的實(shí)例。讀者在閱讀本文的時(shí)候,可以參考閱讀筆者的Java與模式一書(shū)剛由電子工業(yè)出版中的相關(guān)章節(jié)。引言 一個(gè)真實(shí)的工程這是一個(gè)真實(shí)的、面向全球消費(fèi)者的華爾街金融工程的一部份。按照工程方案書(shū),這個(gè)系統(tǒng)是要由數(shù)據(jù)庫(kù)驅(qū)動(dòng)的,并且要支持十九種不同的語(yǔ)言;而且在將來(lái)支持更多的語(yǔ)言。消費(fèi)者在登錄到系統(tǒng)上時(shí)可以選擇自己所需要的語(yǔ)言,系統(tǒng)則根據(jù)用戶的選擇將的靜態(tài)文字和動(dòng)態(tài)文字全部轉(zhuǎn)換為用戶所選擇的語(yǔ)言。經(jīng)過(guò)討論,設(shè)計(jì)師們同意對(duì)靜態(tài)文字和動(dòng)態(tài)文字采取不同的解決方
2、案:把所有的網(wǎng)頁(yè)交給翻譯公司對(duì)上面的靜態(tài)文字進(jìn)展翻譯, 而網(wǎng)頁(yè)上面的動(dòng)態(tài)容則需要程序解決。在進(jìn)展了研究后,設(shè)計(jì)師們發(fā)現(xiàn),他們需要解決的動(dòng)態(tài)文字的翻譯問(wèn)題,實(shí)際上是將數(shù)據(jù)庫(kù)中的一些靜態(tài)或者半靜態(tài)的數(shù)據(jù)進(jìn)展翻譯。下面就是一個(gè)典型的數(shù)據(jù)表:貨幣代碼貨幣名稱貨幣尾數(shù)USDAmerica (United States of America), Dollars2YChina, Yuan Renminbi2EURFrance, Euro2JPYJapan, Yen0代碼清單1、為英文用戶的準(zhǔn)備的貨幣列表。真的不掉線嗎.、.貨幣代碼永遠(yuǎn)是上面所看到的英文代碼,但是貨幣名稱應(yīng)當(dāng)根據(jù)用戶所選擇的語(yǔ)言不同而不同。比
3、方對(duì)中文讀者就應(yīng)當(dāng)翻譯成為下面的表:貨幣代碼貨幣名稱貨幣尾數(shù)USD美國(guó) (美利堅(jiān)合眾國(guó)), 美元2Y中國(guó),人民幣元2EUR法國(guó), 歐元2JPY日本, 日元0代碼清單2、為中文用戶準(zhǔn)備的貨幣列表。這樣的表會(huì)在網(wǎng)頁(yè)上作為下拉菜單出現(xiàn),用戶看到的是貨幣名稱,而系統(tǒng)部使用的是貨幣代碼。國(guó)際化解決方案這樣的問(wèn)題就是國(guó)際化的問(wèn)題,所謂國(guó)際化就是Internationalization,簡(jiǎn)稱作i18n請(qǐng)參見(jiàn)本章最后的問(wèn)答題。設(shè)計(jì)師所采取的實(shí)際方案是分層方案,也就是MVC模式。MVC模式將系統(tǒng)分為三個(gè)層次,也就是模型Model、視圖View、控制器Control三個(gè)部份。國(guó)際化是視圖部份的問(wèn)題,因此應(yīng)當(dāng)在視圖
4、部份得到解決。圖1、MVC模式的示意圖。真的不掉線嗎.、.換言之,系統(tǒng)的核可以是純英文的;在核外部增加一個(gè)殼層負(fù)責(zé)語(yǔ)言翻譯工作。請(qǐng)見(jiàn)下面的概念圖:圖2、英文核和翻譯殼層的概念圖。所謂核就是系統(tǒng)的模型,而翻譯殼層便是視圖的一部份。對(duì)多語(yǔ)言的支持屬于視圖功能,因此不應(yīng)當(dāng)在核解決,而應(yīng)當(dāng)在視圖解決。這就是設(shè)計(jì)師們達(dá)成的總體方案。多態(tài)模式 多態(tài)模式的特點(diǎn)所謂的多態(tài)模式Multiton Pattern,實(shí)際上就是單態(tài)模式的自然推廣。作為對(duì)象的創(chuàng)立模式,多態(tài)模式或多態(tài)類有以下的特點(diǎn):多態(tài)類可有多個(gè)實(shí)例; 多態(tài)類必須自己創(chuàng)立、管理自己的實(shí)例,并向外界提供自己的實(shí)例。單態(tài)類一般情況下最多只可以有一個(gè)實(shí)例,請(qǐng)見(jiàn)
5、下面的構(gòu)造圖:圖3、單態(tài)類的構(gòu)造圖。但是單態(tài)模式的精神是允許有限個(gè)實(shí)例,并不是僅允許一個(gè)實(shí)例;這種最多只允許有限多個(gè)實(shí)例,并向整個(gè)JVM提供自己實(shí)例的類叫做多態(tài)類(Multiton),這種模式叫做多態(tài)模式(Multiton Pattern),請(qǐng)參見(jiàn)下面的構(gòu)造圖。圖4、多態(tài)類的構(gòu)造圖。真的不掉線嗎.、.本章就需要用多態(tài)模式來(lái)實(shí)現(xiàn)資源對(duì)象,需要構(gòu)造出能提供有限個(gè)實(shí)例,每個(gè)實(shí)例有各不一樣的屬性即Locale代碼。有上限多態(tài)類一個(gè)實(shí)例數(shù)目有上限的多態(tài)類已經(jīng)把實(shí)例的上限當(dāng)作邏輯的一部份建造到了多態(tài)類的部;這種多態(tài)模式叫做有上限多態(tài)模式。比方每一麻將牌局都需要兩個(gè)色子,因此色子就應(yīng)當(dāng)是雙態(tài)類。這里就以這個(gè)
6、系統(tǒng)為例,說(shuō)明多態(tài)模式的構(gòu)造。圖5、色子的類圖。下面就是多態(tài)類Die色子的源代碼:package .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(); /*私有的構(gòu)造子保證外界無(wú)法*直接將此類實(shí)例化真的不掉線嗎.、.*/private Die() /*工廠方法*/public static Die getInstanc
7、e(int whichOne)if (whichOne = 1)return die1;elsereturn die2; /*擲色子,返還一個(gè)在1到6之間的*隨機(jī)數(shù)。*/public synchronized int dice()Date d = new Date();Random r = new Random( d.getTime() );int value = r.ne*tInt();value = Math.abs(value);真的不掉線嗎.、.value = value % 6;value += 1;return value;代碼清單3、多態(tài)類的源代碼。在多態(tài)類Die中,使用了餓漢方
8、式創(chuàng)立了兩個(gè)Die的實(shí)例。根據(jù)靜態(tài)工廠方法的參數(shù),工廠方法返還兩個(gè)事例中的一個(gè)。Die對(duì)象的dice()方法代表擲色子,這個(gè)方法會(huì)返還一個(gè)在1到6之間的隨機(jī)數(shù),相當(dāng)于色子的點(diǎn)數(shù)。package .javapatterns.multilingual.dice;public class Clientprivate static Die die1, die2;public static void main(String args)die1 = Die.getInstance(1);die2 = Die.getInstance(2);die1.dice();die2.dice();代碼清單4、客戶端的
9、源代碼。由于有上限的多態(tài)類對(duì)實(shí)例的數(shù)目有上限,因此有上限的多態(tài)類在這個(gè)上限等于1時(shí),多態(tài)類就回到了單態(tài)類。因此多態(tài)類是單態(tài)類的推廣,而單態(tài)類是多態(tài)類的特殊情況。一個(gè)有上限的多態(tài)類可以使用靜態(tài)變量?jī)?chǔ)存所有的實(shí)例;特別是在實(shí)例數(shù)目不多的時(shí)候,可以使用一個(gè)個(gè)的靜態(tài)變量?jī)?chǔ)存一個(gè)個(gè)的實(shí)例。在數(shù)目較多的時(shí)候,就需要使用靜態(tài)聚集儲(chǔ)存這些事例。無(wú)上限多態(tài)模式多態(tài)類的實(shí)例數(shù)目并不需要有上轠CAMP02;實(shí)例數(shù)目沒(méi)有上限的多態(tài)模式就叫做無(wú)上限多態(tài)模式。真的不掉線嗎.、.由于沒(méi)有上限的多態(tài)類對(duì)實(shí)例的數(shù)目是沒(méi)有限制的,因此雖然這種多態(tài)模式是單態(tài)模式的推廣,但是這種多態(tài)類并不一定能夠回到單態(tài)類。由于事先不知道要?jiǎng)?chuàng)立多少
10、個(gè)實(shí)例,因此必然是使用聚集管理所有的實(shí)例。本章要討論的多語(yǔ)言支持方案就需要應(yīng)用到多態(tài)模式,關(guān)于沒(méi)有上限的多態(tài)模式的實(shí)現(xiàn)可以參見(jiàn)下面的討論。圖6、沒(méi)有上限的多態(tài)模式左和有上限的多態(tài)模式右的類圖。其中N就是實(shí)例數(shù)目的上限。有狀態(tài)的和沒(méi)有狀態(tài)的多態(tài)類如同單態(tài)類可以分成有狀態(tài)的和沒(méi)有狀態(tài)的兩種一樣,多態(tài)類也可以分成有狀態(tài)的和沒(méi)有狀態(tài)的兩種。多態(tài)對(duì)象的狀態(tài)如果是可以在加載后改變的,則這種多態(tài)對(duì)象叫做可變多態(tài)對(duì)象Mutable Singleton;如果多態(tài)對(duì)象的狀態(tài)在加載后就不可以改變,則這種多態(tài)對(duì)象叫做不變多態(tài)對(duì)象Immutable Singleton。顯然不變多態(tài)類的情形較為簡(jiǎn)單,而可變單態(tài)類的情形較
11、為復(fù)雜。如果一個(gè)系統(tǒng)是建立在諸如E和RMI等分散技術(shù)之上的,則多態(tài)類有可能會(huì)出現(xiàn)數(shù)個(gè)實(shí)例;因此在這種情況下除非提供有效的協(xié)調(diào)機(jī)制,不然最好不要使用有狀態(tài)的和可變的單態(tài)類,以防止出現(xiàn)狀態(tài)不自恰的情況。讀者可以參考本書(shū)的單態(tài)Singleton模式一章中的相關(guān)討論。多語(yǔ)言工程的設(shè)計(jì)由于熟悉了多態(tài)模式,系統(tǒng)的設(shè)計(jì)實(shí)際上并不復(fù)雜。真的不掉線嗎.、.語(yǔ)言代碼下面就是幾個(gè)常見(jiàn)的語(yǔ)言代碼:語(yǔ)言代碼說(shuō)明de German en English fr French ja Japanese jw Javanese ko Korean zh Chinese 地區(qū)代碼下面就是幾個(gè)常見(jiàn)的地區(qū)代碼:地區(qū)代碼說(shuō)明 China
12、 DE Germany FR France IN India 真的不掉線嗎.、.US United States Locale代碼一個(gè) Locale 代碼由語(yǔ)言代碼和地區(qū)代碼組合而成,比方:語(yǔ)言代碼地區(qū)代碼Locale代碼說(shuō)明enUSen_US美國(guó)英語(yǔ)enGBen_GB英國(guó)英語(yǔ)frFRfr_FR法國(guó)法語(yǔ)frCAfr_CA加拿大法語(yǔ)deDEde_DE德國(guó)德語(yǔ)zhCHzh_CH簡(jiǎn)體漢語(yǔ)代碼清單3、Locale代碼、語(yǔ)言代碼和地區(qū)代碼。Resource文件及其命名規(guī)一個(gè)Resource文件是一個(gè)簡(jiǎn)單的文本文件。一個(gè)Resource文件的名字是由一個(gè)短文件名和文件的擴(kuò)展名properties組成,而R
13、esource文件的短文件名則是Java程序在調(diào)用此文件時(shí)使用的文件名。一個(gè)Resource文件和一個(gè)普通的properties文件并無(wú)本質(zhì)區(qū)別,但Java語(yǔ)言對(duì)兩者的支持是有區(qū)別的。java.util.Properties類不支持多語(yǔ)言,而java.util.ResourceBundle類則支持多語(yǔ)言。當(dāng)Locale代碼是en_US時(shí),Resource文件的文件名應(yīng)當(dāng)是短文件名加上Locale代碼,就是en_US。當(dāng)Locale代碼是zh_CH時(shí),Resource文件的文件名應(yīng)當(dāng)是短文件名加上Locale代碼,就是zh_CH。怎樣使用Locale對(duì)象和ResourceBundle對(duì)象。則怎樣
14、使用 ResourceBundle 讀取一個(gè)Resource文件呢.下面就是一個(gè)例子:真的不掉線嗎.、.Locale locale = new Locale(fr,FR); ResourceBundle res = ResourceBundle.getBundle(shortname,locale);代碼清單4、怎樣使用Locale對(duì)象和ResourceBundle對(duì)象。在上面的例子里面,res對(duì)象會(huì)加載一個(gè)名為shortname_fr_FR.properties的Resource文件。系統(tǒng)的設(shè)計(jì)這里給出系統(tǒng)的構(gòu)造圖。其中LingualResourceTester是一個(gè)示意性的客戶端類,而Li
15、ngualResource是一個(gè)多態(tài)類。圖7、多態(tài)類LingualResource和客戶端類的類圖構(gòu)造。下面就是這個(gè)多態(tài)類的源代碼:package .javapatterns.multilingual;import java.util.HashMap;import java.util.Locale;import java.util.ResourceBundle;public class LingualResourceprivate String language = en;private String region = US;private String localeCode = en_US;
16、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; /*私有的構(gòu)造子保證外界無(wú)法直接將此類實(shí)例化*/private LingualResource(String language, String region)
17、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, region) ,resourceBundle); /*私有的構(gòu)造子保證外界無(wú)法直接將此類實(shí)例化*/private LingualRes
18、ource()file:/do nothing /*真的不掉線嗎.、.*工廠方法,返還一個(gè)具有指定的部狀態(tài)的實(shí)例*/public synchronized static LingualResourcegetInstance(String language, String region)if (instances.containsKey(makeLocaleCode(language , region )return (LingualResource) instances.get(makeLocaleCode(language , region );elsereturn newLingualRe
19、source(language, region);public String getLocaleString(String code)return resourceBundle.getString(code);private static String makeLocaleCode(String language, String region)return language + _ + region;代碼清單5、多態(tài)類LingualResource的源代碼。其中的makeLocaleCode()是一個(gè)輔助性的方法,在傳入語(yǔ)言代碼和地區(qū)代碼時(shí),此方法可以返回一個(gè)Locale代碼。 這個(gè)多態(tài)類的構(gòu)
20、造子是私有的,因此不能用new關(guān)鍵字來(lái)實(shí)例化。所有的實(shí)例必須通過(guò)調(diào)用靜態(tài)getInstance()方法來(lái)得到。在getInstance()方法被調(diào)用時(shí),程序會(huì)首先檢查傳入的Locale代碼是否已經(jīng)在instances集合中存在;如果已經(jīng)存在,即直接返回它所對(duì)應(yīng)的LingualResource對(duì)象,否則就會(huì)首先創(chuàng)立一個(gè)這個(gè)Locale代碼所對(duì)應(yīng)的LingualResource對(duì)象,將之存入instances集合,并返回這個(gè)實(shí)例。 下面給出一個(gè)客戶端的源代碼:真的不掉線嗎.、.package .javapatterns.multilingual;public class LingualResour
21、ceTesterpublic static void main(String args)LingualResource ling =LingualResource.getInstance(en , US);String usDollar = ling.getLocaleString(USD);System.out.println(USD= + usDollar);LingualResource lingZh =LingualResource.getInstance(zh , CH);String usDollarZh = lingZh.getLocaleString(USD);System.o
22、ut.println(USD= + usDollarZh);代碼清單6、客戶端類LingualResourceTester的源代碼。如果用戶是美國(guó)用戶,則在JSP網(wǎng)頁(yè)中可以通過(guò)調(diào)用getLocaleString()方法得到相應(yīng)的英文說(shuō)明。比方:LingualResource ling = LingualResource.getInstance(en , US);String usDollar = ling.getLocaleString(USD);就會(huì)返還US Dollar真的不掉線嗎.、.相應(yīng)地,如果用戶是中國(guó)大陸的用戶,則在JSP網(wǎng)頁(yè)中可以通過(guò)調(diào)用getLocaleString()方法得到
23、相應(yīng)的中文說(shuō)明。比方,LingualResource ling = LingualResource.getInstance(zh , CH);String usDollar = ling.getLocaleString(USD);就會(huì)返還美元Resource文件的容 為美國(guó)英文準(zhǔn)備的Resource文件res_en_US.properties的容如下:USD=US DollarJPY=Japanese Yen代碼清單7、Resource文件res_en_US.properties的容。 為簡(jiǎn)體中文準(zhǔn)備的Resource文件res_zh_CH.properties的容如下:USD=美元JPY=日
24、元代碼清單8、Resource文件res_zh_CH.properties的容。 問(wèn)答題真的不掉線嗎.、.第一題、請(qǐng)問(wèn)為什么Internationalization又簡(jiǎn)稱作i18n.第二題、請(qǐng)給出一個(gè)根據(jù)語(yǔ)言代碼和地區(qū)代碼將數(shù)目字格式化的例子。第三題、請(qǐng)給出一個(gè)根據(jù)語(yǔ)言代碼和地區(qū)代碼將貨幣數(shù)目字格式化的例子。第四題、請(qǐng)給出一個(gè)根據(jù)語(yǔ)言代碼和地區(qū)代碼將百分比格式化的例子。問(wèn)答題答案第一題答案、在英文字Internationalization中,第一個(gè)字母i和最后一個(gè)字母n之間有18個(gè)字母,因此Internationalization又簡(jiǎn)稱作i18n。第二題答案、Java庫(kù)java.te*t.Nu
25、mberFormat類提供了對(duì)數(shù)目字格式的支持,下面給出的就是解答的類圖:圖8、對(duì)數(shù)目字格式支持的解答。程序的源代碼如下:package .javapatterns.multilingual.number;import java.util.Locale;import java.te*t.NumberFormat;public class NumberFormatTester static public void displayNumber(真的不掉線嗎.、. Double amount, Locale currentLocale) NumberFormat formatter;String a
26、mountOut;formatter =NumberFormat.getNumberInstance(currentLocale);amountOut = formatter.format(amount);System.out.println(amountOut + + currentLocale.toString(); static public void main(String args) displayNumber(new Double(1234567.89),new Locale(en, US);displayNumber(new Double(1234567.89),new Loca
27、le(de, DE);displayNumber(new Double(1234567.89),new Locale(fr, FR); 代碼清單9、Resource文件res_zh_CH.properties的容。在運(yùn)行時(shí),程序回打印出下面的結(jié)果:456,789% en_US456.789% de_DE真的不掉線嗎.、.456 789% fr_FR代碼清單10、Resource文件res_zh_CH.properties的容。 第三題答案、Java庫(kù)java.te*t.NumberFormat類提供了對(duì)貨幣數(shù)目格式的支持。下面給出的就是解答的類圖:圖9、對(duì)貨幣數(shù)目格式支持的解答。程序的源代碼如
28、下:package .javapatterns.multilingual.number;import java.util.Locale;import java.te*t.NumberFormat;public class CurrencyFormatTesterstatic public void displayCurrency(Double amount,Locale currentLocale) NumberFormat formatter; String amountOut; formatter =NumberFormat.getCurrencyInstance(currentLocal
29、e); 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); displayCurrency(new Double(1234567.89), new Locale(de, DE); displayCurrency(new Double(1234567.89), new Locale(fr, FR);代碼清單11、Resource文件res_zh_CH.properties的容。在運(yùn)行時(shí),程序回打印出下面的結(jié)果:$1,234,567.89 en_US1.234.567,89 D
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 養(yǎng)老院入住管理制度
- 企業(yè)內(nèi)部培訓(xùn)與成長(zhǎng)制度
- 公共交通票務(wù)管理制度
- 2026年金融風(fēng)險(xiǎn)控制師知識(shí)水平測(cè)試題集
- 2026年兒科常見(jiàn)手術(shù)操作技巧與考試題
- 2026年?duì)I養(yǎng)師職業(yè)資格考試營(yíng)養(yǎng)學(xué)與膳食管理題庫(kù)集
- 2026年中級(jí)財(cái)務(wù)會(huì)計(jì)考試題目及解析
- 2026年會(huì)計(jì)職稱考試題庫(kù)與答案解析
- 2026年農(nóng)業(yè)項(xiàng)目驗(yàn)收協(xié)議(全面·達(dá)標(biāo)版)
- 護(hù)理措施精準(zhǔn)化選擇
- 2025年司法鑒定人資格考試歷年真題試題及答案
- 江蘇省連云港市2024-2025學(xué)年第一學(xué)期期末調(diào)研考試高二歷史試題
- 生成式人工智能與初中歷史校本教研模式的融合與創(chuàng)新教學(xué)研究課題報(bào)告
- 2025年湖北煙草專賣局筆試試題及答案
- 2026年開(kāi)工第一課復(fù)工復(fù)產(chǎn)安全專題培訓(xùn)
- 特殊人群(老人、兒童)安全護(hù)理要點(diǎn)
- 2026年檢察院書(shū)記員面試題及答案
- 《煤礦安全規(guī)程(2025)》防治水部分解讀課件
- 2025至2030中國(guó)新癸酸縮水甘油酯行業(yè)項(xiàng)目調(diào)研及市場(chǎng)前景預(yù)測(cè)評(píng)估報(bào)告
- 2025年保安員職業(yè)技能考試筆試試題(100題)含答案
- 尾礦庫(kù)閉庫(kù)綜合治理工程項(xiàng)目可行性研究報(bào)告
評(píng)論
0/150
提交評(píng)論