Java模式設(shè)計之多態(tài)模式多語言支持_第1頁
Java模式設(shè)計之多態(tài)模式多語言支持_第2頁
Java模式設(shè)計之多態(tài)模式多語言支持_第3頁
Java模式設(shè)計之多態(tài)模式多語言支持_第4頁
Java模式設(shè)計之多態(tài)模式多語言支持_第5頁
已閱讀5頁,還剩32頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、-. zJava模式設(shè)計之多態(tài)模式與多語言支持作為對象的創(chuàng)立模式,多態(tài)模式中的多態(tài)類可有多個實例;而且多態(tài)類必須自己創(chuàng)立、管理自己的實例,并向外界提供自己的實例。讀者在閱讀本文的時候,可以參考閱讀筆者的Java與模式一書剛由電子工業(yè)出版中的相關(guān)章節(jié)。引言 一個真實的工程這是一個真實的、面向全球消費者的華爾街金融工程的一部份。按照工程方案書,這個系統(tǒng)是要由數(shù)據(jù)庫驅(qū)動的,并且要支持十九種不同的語言;而且在將來支持更多的語言。消費者在登錄到系統(tǒng)上時可以選擇自己所需要的語言,系統(tǒng)則根據(jù)用戶的選擇將的靜態(tài)文字和動態(tài)文字全部轉(zhuǎn)換為用戶所選擇的語言。經(jīng)過討論,設(shè)計師們同意對靜態(tài)文字和動態(tài)文字采取不同的解決方

2、案:把所有的網(wǎng)頁交給翻譯公司對上面的靜態(tài)文字進展翻譯, 而網(wǎng)頁上面的動態(tài)容則需要程序解決。在進展了研究后,設(shè)計師們發(fā)現(xiàn),他們需要解決的動態(tài)文字的翻譯問題,實際上是將數(shù)據(jù)庫中的一些靜態(tài)或者半靜態(tài)的數(shù)據(jù)進展翻譯。下面就是一個典型的數(shù)據(jù)表:貨幣代碼貨幣名稱貨幣尾數(shù)USDAmerica (United States of America), Dollars2YChina, Yuan Renminbi2EURFrance, Euro2JPYJapan, Yen0代碼清單1、為英文用戶的準(zhǔn)備的貨幣列表。真的不掉線嗎.、.貨幣代碼永遠(yuǎn)是上面所看到的英文代碼,但是貨幣名稱應(yīng)當(dāng)根據(jù)用戶所選擇的語言不同而不同。比

3、方對中文讀者就應(yīng)當(dāng)翻譯成為下面的表:貨幣代碼貨幣名稱貨幣尾數(shù)USD美國 (美利堅合眾國), 美元2Y中國,人民幣元2EUR法國, 歐元2JPY日本, 日元0代碼清單2、為中文用戶準(zhǔn)備的貨幣列表。這樣的表會在網(wǎng)頁上作為下拉菜單出現(xiàn),用戶看到的是貨幣名稱,而系統(tǒng)部使用的是貨幣代碼。國際化解決方案這樣的問題就是國際化的問題,所謂國際化就是Internationalization,簡稱作i18n請參見本章最后的問答題。設(shè)計師所采取的實際方案是分層方案,也就是MVC模式。MVC模式將系統(tǒng)分為三個層次,也就是模型Model、視圖View、控制器Control三個部份。國際化是視圖部份的問題,因此應(yīng)當(dāng)在視圖

4、部份得到解決。圖1、MVC模式的示意圖。真的不掉線嗎.、.換言之,系統(tǒng)的核可以是純英文的;在核外部增加一個殼層負(fù)責(zé)語言翻譯工作。請見下面的概念圖:圖2、英文核和翻譯殼層的概念圖。所謂核就是系統(tǒng)的模型,而翻譯殼層便是視圖的一部份。對多語言的支持屬于視圖功能,因此不應(yīng)當(dāng)在核解決,而應(yīng)當(dāng)在視圖解決。這就是設(shè)計師們達(dá)成的總體方案。多態(tài)模式 多態(tài)模式的特點所謂的多態(tài)模式Multiton Pattern,實際上就是單態(tài)模式的自然推廣。作為對象的創(chuàng)立模式,多態(tài)模式或多態(tài)類有以下的特點:多態(tài)類可有多個實例; 多態(tài)類必須自己創(chuàng)立、管理自己的實例,并向外界提供自己的實例。單態(tài)類一般情況下最多只可以有一個實例,請見

5、下面的構(gòu)造圖:圖3、單態(tài)類的構(gòu)造圖。但是單態(tài)模式的精神是允許有限個實例,并不是僅允許一個實例;這種最多只允許有限多個實例,并向整個JVM提供自己實例的類叫做多態(tài)類(Multiton),這種模式叫做多態(tài)模式(Multiton Pattern),請參見下面的構(gòu)造圖。圖4、多態(tài)類的構(gòu)造圖。真的不掉線嗎.、.本章就需要用多態(tài)模式來實現(xiàn)資源對象,需要構(gòu)造出能提供有限個實例,每個實例有各不一樣的屬性即Locale代碼。有上限多態(tài)類一個實例數(shù)目有上限的多態(tài)類已經(jīng)把實例的上限當(dāng)作邏輯的一部份建造到了多態(tài)類的部;這種多態(tài)模式叫做有上限多態(tài)模式。比方每一麻將牌局都需要兩個色子,因此色子就應(yīng)當(dāng)是雙態(tài)類。這里就以這個

6、系統(tǒng)為例,說明多態(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)造子保證外界無法*直接將此類實例化真的不掉線嗎.、.*/private Die() /*工廠方法*/public static Die getInstanc

7、e(int whichOne)if (whichOne = 1)return die1;elsereturn die2; /*擲色子,返還一個在1到6之間的*隨機數(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)立了兩個Die的實例。根據(jù)靜態(tài)工廠方法的參數(shù),工廠方法返還兩個事例中的一個。Die對象的dice()方法代表擲色子,這個方法會返還一個在1到6之間的隨機數(shù),相當(dāng)于色子的點數(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)類對實例的數(shù)目有上限,因此有上限的多態(tài)類在這個上限等于1時,多態(tài)類就回到了單態(tài)類。因此多態(tài)類是單態(tài)類的推廣,而單態(tài)類是多態(tài)類的特殊情況。一個有上限的多態(tài)類可以使用靜態(tài)變量儲存所有的實例;特別是在實例數(shù)目不多的時候,可以使用一個個的靜態(tài)變量儲存一個個的實例。在數(shù)目較多的時候,就需要使用靜態(tài)聚集儲存這些事例。無上限多態(tài)模式多態(tài)類的實例數(shù)目并不需要有上轠CAMP02;實例數(shù)目沒有上限的多態(tài)模式就叫做無上限多態(tài)模式。真的不掉線嗎.、.由于沒有上限的多態(tài)類對實例的數(shù)目是沒有限制的,因此雖然這種多態(tài)模式是單態(tài)模式的推廣,但是這種多態(tài)類并不一定能夠回到單態(tài)類。由于事先不知道要創(chuàng)立多少

10、個實例,因此必然是使用聚集管理所有的實例。本章要討論的多語言支持方案就需要應(yīng)用到多態(tài)模式,關(guān)于沒有上限的多態(tài)模式的實現(xiàn)可以參見下面的討論。圖6、沒有上限的多態(tài)模式左和有上限的多態(tài)模式右的類圖。其中N就是實例數(shù)目的上限。有狀態(tài)的和沒有狀態(tài)的多態(tài)類如同單態(tài)類可以分成有狀態(tài)的和沒有狀態(tài)的兩種一樣,多態(tài)類也可以分成有狀態(tài)的和沒有狀態(tài)的兩種。多態(tài)對象的狀態(tài)如果是可以在加載后改變的,則這種多態(tài)對象叫做可變多態(tài)對象Mutable Singleton;如果多態(tài)對象的狀態(tài)在加載后就不可以改變,則這種多態(tài)對象叫做不變多態(tài)對象Immutable Singleton。顯然不變多態(tài)類的情形較為簡單,而可變單態(tài)類的情形較

11、為復(fù)雜。如果一個系統(tǒng)是建立在諸如E和RMI等分散技術(shù)之上的,則多態(tài)類有可能會出現(xiàn)數(shù)個實例;因此在這種情況下除非提供有效的協(xié)調(diào)機制,不然最好不要使用有狀態(tài)的和可變的單態(tài)類,以防止出現(xiàn)狀態(tài)不自恰的情況。讀者可以參考本書的單態(tài)Singleton模式一章中的相關(guān)討論。多語言工程的設(shè)計由于熟悉了多態(tài)模式,系統(tǒng)的設(shè)計實際上并不復(fù)雜。真的不掉線嗎.、.語言代碼下面就是幾個常見的語言代碼:語言代碼說明de German en English fr French ja Japanese jw Javanese ko Korean zh Chinese 地區(qū)代碼下面就是幾個常見的地區(qū)代碼:地區(qū)代碼說明 China

12、 DE Germany FR France IN India 真的不掉線嗎.、.US United States Locale代碼一個 Locale 代碼由語言代碼和地區(qū)代碼組合而成,比方:語言代碼地區(qū)代碼Locale代碼說明enUSen_US美國英語enGBen_GB英國英語frFRfr_FR法國法語frCAfr_CA加拿大法語deDEde_DE德國德語zhCHzh_CH簡體漢語代碼清單3、Locale代碼、語言代碼和地區(qū)代碼。Resource文件及其命名規(guī)一個Resource文件是一個簡單的文本文件。一個Resource文件的名字是由一個短文件名和文件的擴展名properties組成,而R

13、esource文件的短文件名則是Java程序在調(diào)用此文件時使用的文件名。一個Resource文件和一個普通的properties文件并無本質(zhì)區(qū)別,但Java語言對兩者的支持是有區(qū)別的。java.util.Properties類不支持多語言,而java.util.ResourceBundle類則支持多語言。當(dāng)Locale代碼是en_US時,Resource文件的文件名應(yīng)當(dāng)是短文件名加上Locale代碼,就是en_US。當(dāng)Locale代碼是zh_CH時,Resource文件的文件名應(yīng)當(dāng)是短文件名加上Locale代碼,就是zh_CH。怎樣使用Locale對象和ResourceBundle對象。則怎樣

14、使用 ResourceBundle 讀取一個Resource文件呢.下面就是一個例子:真的不掉線嗎.、.Locale locale = new Locale(fr,FR); ResourceBundle res = ResourceBundle.getBundle(shortname,locale);代碼清單4、怎樣使用Locale對象和ResourceBundle對象。在上面的例子里面,res對象會加載一個名為shortname_fr_FR.properties的Resource文件。系統(tǒng)的設(shè)計這里給出系統(tǒng)的構(gòu)造圖。其中LingualResourceTester是一個示意性的客戶端類,而Li

15、ngualResource是一個多態(tài)類。圖7、多態(tài)類LingualResource和客戶端類的類圖構(gòu)造。下面就是這個多態(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)造子保證外界無法直接將此類實例化*/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)造子保證外界無法直接將此類實例化*/private LingualRes

18、ource()file:/do nothing /*真的不掉線嗎.、.*工廠方法,返還一個具有指定的部狀態(tài)的實例*/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()是一個輔助性的方法,在傳入語言代碼和地區(qū)代碼時,此方法可以返回一個Locale代碼。 這個多態(tài)類的構(gòu)

20、造子是私有的,因此不能用new關(guān)鍵字來實例化。所有的實例必須通過調(diào)用靜態(tài)getInstance()方法來得到。在getInstance()方法被調(diào)用時,程序會首先檢查傳入的Locale代碼是否已經(jīng)在instances集合中存在;如果已經(jīng)存在,即直接返回它所對應(yīng)的LingualResource對象,否則就會首先創(chuàng)立一個這個Locale代碼所對應(yīng)的LingualResource對象,將之存入instances集合,并返回這個實例。 下面給出一個客戶端的源代碼:真的不掉線嗎.、.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的源代碼。如果用戶是美國用戶,則在JSP網(wǎng)頁中可以通過調(diào)用getLocaleString()方法得到相應(yīng)的英文說明。比方:LingualResource ling = LingualResource.getInstance(en , US);String usDollar = ling.getLocaleString(USD);就會返還US Dollar真的不掉線嗎.、.相應(yīng)地,如果用戶是中國大陸的用戶,則在JSP網(wǎng)頁中可以通過調(diào)用getLocaleString()方法得到

23、相應(yīng)的中文說明。比方,LingualResource ling = LingualResource.getInstance(zh , CH);String usDollar = ling.getLocaleString(USD);就會返還美元Resource文件的容 為美國英文準(zhǔn)備的Resource文件res_en_US.properties的容如下:USD=US DollarJPY=Japanese Yen代碼清單7、Resource文件res_en_US.properties的容。 為簡體中文準(zhǔn)備的Resource文件res_zh_CH.properties的容如下:USD=美元JPY=日

24、元代碼清單8、Resource文件res_zh_CH.properties的容。 問答題真的不掉線嗎.、.第一題、請問為什么Internationalization又簡稱作i18n.第二題、請給出一個根據(jù)語言代碼和地區(qū)代碼將數(shù)目字格式化的例子。第三題、請給出一個根據(jù)語言代碼和地區(qū)代碼將貨幣數(shù)目字格式化的例子。第四題、請給出一個根據(jù)語言代碼和地區(qū)代碼將百分比格式化的例子。問答題答案第一題答案、在英文字Internationalization中,第一個字母i和最后一個字母n之間有18個字母,因此Internationalization又簡稱作i18n。第二題答案、Java庫java.te*t.Nu

25、mberFormat類提供了對數(shù)目字格式的支持,下面給出的就是解答的類圖:圖8、對數(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的容。在運行時,程序回打印出下面的結(jié)果:456,789% en_US456.789% de_DE真的不掉線嗎.、.456 789% fr_FR代碼清單10、Resource文件res_zh_CH.properties的容。 第三題答案、Java庫java.te*t.NumberFormat類提供了對貨幣數(shù)目格式的支持。下面給出的就是解答的類圖:圖9、對貨幣數(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的容。在運行時,程序回打印出下面的結(jié)果:$1,234,567.89 en_US1.234.567,89 D

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論