深入淺出Java設(shè)計(jì)模式_第1頁(yè)
深入淺出Java設(shè)計(jì)模式_第2頁(yè)
深入淺出Java設(shè)計(jì)模式_第3頁(yè)
深入淺出Java設(shè)計(jì)模式_第4頁(yè)
深入淺出Java設(shè)計(jì)模式_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、通常,客戶類(lèi)(clients of class)通過(guò)類(lèi)的接口訪問(wèn)它提供的服務(wù)。有時(shí), 現(xiàn)有的類(lèi)(existing class)可以提供客戶類(lèi)的功 能需要,但是它所提供的接 口不一定是客戶類(lèi)所期望的。這是由于現(xiàn)有的接口太詳細(xì)或者缺乏詳細(xì)或接口的 名稱(chēng)與客戶類(lèi)所查找的不同等諸多不同原因?qū)е碌?。在這種情況下,現(xiàn)有的接口需要轉(zhuǎn)化(convert)為客戶類(lèi)期望的接口,這 樣保證了對(duì)現(xiàn)有類(lèi)的重用。如果不進(jìn)行這樣的轉(zhuǎn)化,客戶類(lèi)就不能利用現(xiàn)有類(lèi)所 提供的功能。適配器模式(Adapter Pattern)可以完成這樣的轉(zhuǎn)化。適配器模式建議定義一 個(gè)包裝類(lèi),包裝有不兼容接口的對(duì)象。這個(gè)包裝類(lèi)指的就是適配器(Ada

2、pter), 它包裝的對(duì)象就是適配者(Adaptee)。適配器提供客戶類(lèi)需要的接口,適配器接口的實(shí)現(xiàn)是把客戶類(lèi)的請(qǐng)求轉(zhuǎn)化為對(duì)適 配 者的相應(yīng)接口的調(diào)用。換句話說(shuō):當(dāng)客戶類(lèi)調(diào)用適配器的方法時(shí),在適配器 類(lèi)的內(nèi)部調(diào)用適配者類(lèi)的方法,這個(gè)過(guò)程對(duì)客戶類(lèi)是透明的,客戶類(lèi)并不直接訪 問(wèn)適配者 類(lèi)。因此,適配器可以使由于借口不兼容而不能交互的類(lèi)可以一起工 作(work together)。在上面討論的接口:不是指在JAVA編程語(yǔ)言中接口的概念,雖然類(lèi)的接口可以通過(guò) JAVA借擴(kuò)來(lái)定義。不是指由窗體和GUI控件所組成的GUI應(yīng)用程序的用戶接口。而是指類(lèi)所報(bào)漏的,被其他類(lèi)調(diào)用的編程接口,類(lèi)適配器(Class A

3、dapter)VS 對(duì)象適配器(Object Adapter)適配器總體上可以分為兩類(lèi)?類(lèi)適配器(Class Adapter)VS對(duì)象適配器 (Object Adapter)類(lèi)適配器:類(lèi)適配器是通過(guò)繼承類(lèi)適配者類(lèi)(Adaptee Class)實(shí)現(xiàn)的,另外類(lèi)適配器 實(shí)現(xiàn)客戶類(lèi)所需要的接口。當(dāng)客戶對(duì)象調(diào)用適配器類(lèi)方法的時(shí)候,適配器內(nèi)部調(diào) 用它所繼承的適配者的方法。對(duì)象適配器:對(duì)象適配器包含一個(gè)適配器者的引用(reference),與類(lèi)適配器相同,對(duì) 象適配器也實(shí)現(xiàn)了客戶類(lèi)需要的接口。當(dāng)客戶對(duì)象調(diào)用對(duì)象適配器的方法的時(shí) 候,對(duì)象適配器調(diào)它所包含的適配器者實(shí)例的適當(dāng)方法。下表是類(lèi)適配器(Class A

4、dapter)和對(duì)象適配器(Object Adapter)的詳細(xì) 不同:類(lèi)適配器)對(duì)象窗己器:OEj以竟埋就基于縫承撞念利用對(duì)蒙合成只能應(yīng)用在適配者是接口,不能利用它子類(lèi) 的接口,當(dāng)類(lèi)適配器建立時(shí),它就靜態(tài)地與 適配者關(guān)聯(lián)可以應(yīng)用在適配者是接口和它的所有子類(lèi)因?yàn)檫m1己器是作為適配者的子類(lèi),所以適配 器可能會(huì)重載適目睹的一些行為。注意:在中,子類(lèi)不育載父類(lèi)中聲 明為fii詛1的方法口不能重載適配者的方法。注意:字面上,不能重栽只是因?yàn)闆](méi)有繼承。但是適配器提供包裝方法可以按需要改變行 為口客戶類(lèi)對(duì)適配者中聲明為public的接口是可 見(jiàn)的,在JAVA應(yīng)用程序中:適用于期待的接口是心接口的形式,而

5、不是抽象地或具體地類(lèi)的形式-這是因?yàn)?點(diǎn)我端程語(yǔ)言只允許單縫承。因此,類(lèi)適配 器設(shè)計(jì)成適配者的子類(lèi)??蛻纛?lèi)和適配者是完全不關(guān)聯(lián)的,只有適配 器才有矗知適配者接口。在JAV-%應(yīng)用程序中:適用于當(dāng)客戶對(duì)象期望的接口是抽象類(lèi)的形 式,同時(shí)也可以應(yīng)用于期望接口是Ja作接口 的形式。補(bǔ)充:類(lèi)適配器(Class Adapter)對(duì)象適配器(Object Adapter)基于繼承概念利用對(duì)象合成只能應(yīng)用在適配者是接口,不能利用它子類(lèi)的接口,當(dāng)類(lèi)適配器建立時(shí),它 就靜態(tài)地與適配者關(guān)聯(lián) 可以應(yīng)用在適配者是接口和它的所有子類(lèi),因?yàn)檫m配 器是作為適配者的子類(lèi),所以適配器可能會(huì)重載適配者的一些行為。注意:在JAVA

6、中,子類(lèi)不能重載父類(lèi)中聲明為final的方法。不能重載適配者的方法。注意:字面上,不能重栽只是因?yàn)闆](méi)有繼承。但是適配器提供包裝方法可以 按需要改變行為??蛻纛?lèi)對(duì)適配者中聲明為public的接口是可見(jiàn)的,客戶類(lèi)和適配者是完全不關(guān)聯(lián)的,只有適配器才能感知適配者接口。在JAVA應(yīng)用程序中:適用于期待的接口是JAVA接口的形式,而不是抽象地或具體地類(lèi)的形式。這是因?yàn)镴AVA編程語(yǔ)言只允許單繼承。因此,類(lèi)適配器設(shè)計(jì)成適配者的子類(lèi)。 在JAVA應(yīng)用程序中:適用于當(dāng)客戶對(duì)象期望的接口是抽象類(lèi)的形式,同時(shí)也可以應(yīng)用于期望接口是 Java接口的形式。例子:讓我們建立一個(gè)驗(yàn)證給定客戶地址的應(yīng)用。這個(gè)應(yīng)用是作為大的

7、客戶數(shù)據(jù)管 理應(yīng)用的一部分。讓我們定義一個(gè)Customer類(lèi):CustomerFigure 20.1: Customer ClassListing 20.1: Customer Classclass Customer (2.3.4.5.6.class Customer (2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.public static final String public private private private publicstatic final StringStringStringString booleanUS = US;C

8、ANADA = Canada;publicaddress;name;zip, state,type;isValidAddress() (Customer(String inp_name, String inp_address, String inp_zip, String inp_state, String inp_type) (name address zip = statetype =inp_name;=inp_address;inp_zip;二 inp_state;inp_type; /end of class不同的客戶對(duì)象創(chuàng)建Customer對(duì)象并調(diào)用(invoke) isValidA

9、ddress方 法驗(yàn)證客戶地址的有效性。為了驗(yàn)證客戶地址的有效性,Customer類(lèi)期望利用 一個(gè)地址驗(yàn)證類(lèi)(address validator class),這個(gè)驗(yàn)證類(lèi)提供了在接口 AddressValidator 中聲明的接口。Listing 20.2: AddressValidator as an Interfacepublic interface AddressValidator (public boolean isValidAddress(String inp_address,String inp_zip, String inp_state);/end of class讓我們定義一個(gè)

10、USAddress的驗(yàn)證類(lèi),來(lái)驗(yàn)證給定的U.S地址。Listing 20.3: USAddress Classclass USAddress implements AddressValidator (public boolean isValidAddress(String inp_address,String inp_zip, String inp_state) (if (inp_address.trim(). length () 10)return false;if (inp_zip.trim(). length() 10)return false;if (inp_state.trim().

11、 length() != 2)return false;return true;/end of classUSAddress 類(lèi)實(shí)現(xiàn) AddressValidator 接口,因此 Customer 對(duì)象使用 USAddress實(shí)例作為驗(yàn)證客戶地址過(guò)程的一部分是沒(méi)有任何問(wèn)題的。Listing 20.4: Customer Class Using the USAddress Classclass Customer (public boolean isValidAddress() (/get an appropriate address validatorAddressValidator valid

12、ator = getValidator(type);/Polymorphic call to validate the addressreturn validator.isValidAddress(address, zip, state);private AddressValidator getValidator(String custType) (AddressValidator validator = null;if (custType.equals(Customer.US) (validator = new USAddress();return validator; /end of cl

13、assFigure 20.2: Customer/USAddress Validator?Class Association但是當(dāng)驗(yàn)證來(lái)自加拿大的客戶時(shí),就要對(duì)應(yīng)用進(jìn)行改進(jìn)。這需要一個(gè)驗(yàn)證加 拿大客戶地址的驗(yàn)證類(lèi)。讓我們假設(shè)已經(jīng)存在一個(gè)用來(lái)驗(yàn)證加拿大客戶地址的使 用工具類(lèi)CAAddress。從下面的CAAdress類(lèi)的實(shí)現(xiàn),可以發(fā)現(xiàn)CAAdress提供了客戶類(lèi)Customer類(lèi)所 需要的驗(yàn)證服務(wù)。但是它所提供的接口不用于客戶類(lèi)Customer所期望的。Listing 20.5: CAAdress Class with Incompatible Interfaceclass CAAddress

14、(public boolean isValidCanadianAddr(String inp_address,String inp_pcode, String inp_prvnc) (if (inp_address.trim(). length () 15)return false;if (inp_pcode.trim(). length() != 6)return false;if (inp_prvnc.trim(). length () 6)return false;return true;/end of classCAAdress 類(lèi)提供了一個(gè) isValidCanadianAddr 方

15、法,但是 Customer 期望一 個(gè)聲明在 AddressValidator 接口中的 isValidAddress 方法。接口的不兼容使得Customer對(duì)象利用現(xiàn)有的CAAdress類(lèi)是困難的。一種意 見(jiàn)是改變CAAdress類(lèi)的接口,但是可能會(huì)有其他的應(yīng)用正在使用CAAdress類(lèi)的 這種形式。改變CAAdress類(lèi)接口會(huì)影響現(xiàn)在使用CAAdress類(lèi)的客戶。應(yīng)用適配器模式,類(lèi)適配器CAAdressAdapter可以繼承CAAdress類(lèi)實(shí)現(xiàn) AddressValidator 接口。Figure 20.3: Class Adapter for the CAAddress ClassLi

16、sting 20.6: CAAddressAdapter as a Class Adapterpublic class CAAddressAdapter extends CAAddressimplements AddressValidator (public boolean isValidAddress(String inp_address,String inp_zip, String inp_state) (return isValidCanadianAddr(inp_address, inp_zip,inp_state);/end of class因?yàn)檫m配器CAAdressAdapter實(shí)

17、現(xiàn)了 AddressValidator接口,客戶端對(duì)象 訪問(wèn)適配器CAAdressAdapter對(duì)象是沒(méi) 有任何問(wèn)題的。當(dāng)客戶對(duì)象調(diào)用適配器 實(shí)例的isValidAddress方法的時(shí)候,適配器在內(nèi)部把調(diào)用傳遞給它繼承的 isValidCanadianAddr 方法。在Customer類(lèi)內(nèi)部,getValidator私有方法需要擴(kuò)展,以至于它可以 在 驗(yàn)證加拿大客戶的時(shí)候返回一個(gè)CAAdressAdapter實(shí)例。返回的對(duì)象是多態(tài)的, USAddress 和 CAAddressAdapter 都實(shí)現(xiàn) 了 AddressValidator 接口,所以不用 改變。Listing 20.7: Cus

18、tomer Class Using the CAAddressAdapter Classclass Customer (public boolean isValidAddress() (/get an appropriate address validatorAddressValidator validator = getValidator(type);/Polymorphiccall to validate the addressreturn validator.isValidAddress(address, zip, state); TOC o 1-5 h z private Addres

19、sValidator getValidator(String custType) (AddressValidator validator = null;if(custType.equals(Customer.US)(validator = new USAddress();if(type.equals(Customer.CANADA)(validator = new CAAddressAdapter();return validator;/end of classCAAddressAdapter設(shè)計(jì)和對(duì)AddressValidator (聲明期望的接口)對(duì)象的 多態(tài)調(diào)用使Customer可以利用

20、接口不兼容CAAddress類(lèi)提供的服務(wù)。Figure 20.4: Address Validation Application?Using Class AdapterFigure 20.5: Address Validation Message Flow?Using Class Adapter作為對(duì)象適配器的地址適配器當(dāng)討論以類(lèi)適配器來(lái)實(shí)現(xiàn)地址適配器時(shí),我們說(shuō)客戶類(lèi)期望的 AddressValidator接口是Java接口形式。現(xiàn)在,讓我們假設(shè)客戶類(lèi)期望 AddressValidator接口是抽象類(lèi)而不是java接口。因?yàn)檫m配器CAAdapter必須 提供抽象類(lèi)AddressValidatr

21、o中聲明 的接口,適配器必須是AddressValidator 抽象類(lèi)的子類(lèi)、實(shí)現(xiàn)抽象方法。Listing 20.8: AddressValidator as an Abstract Classpublic abstract class AddressValidator (public abstract boolean isValidAddress(String inp_address,String inp_zip, String inp_state);/end of classListing 20.9: CAAddressAdapter Classclass CAAddressAdapter

22、 extends AddressValidator (public CAAddressAdapter(CAAddress address) (objCAAddress = address; TOC o 1-5 h z public boolean isValidAddress(String inp_address,String inp_zip, String inp_state) ( /end of class因?yàn)槎嗬^承在JAVA中不支持,現(xiàn)在適配器CAAddressAdapter不能繼承現(xiàn)有 的CAAddress類(lèi),它已經(jīng)使用了唯一一次繼承其他類(lèi)的機(jī)會(huì)。應(yīng)用對(duì)象適配器模式,CAAddressAdapter可以包含一個(gè)適配者CAAddress 的一個(gè)實(shí)例。當(dāng)適配器第一次創(chuàng)建的時(shí)候,這個(gè)適配者的實(shí)例通過(guò)客戶端傳遞給 適配器。通常,適配者實(shí)例可以通過(guò)下面兩種方式提供給包裝它的適配器。(1)對(duì)象適配器的客戶端可以傳遞一個(gè)適配者的實(shí)例給適配器。這種 方式在選擇類(lèi)的形式上有很大的靈活性,但是客戶端感知了適配者或者適配過(guò) 程。這種方法在適配器不但需要適配者對(duì)象行為而且需要特定狀態(tài)時(shí)很適合。(2)適配器可以自己創(chuàng)建適配者實(shí)例。這種方法相對(duì)來(lái)說(shuō)缺乏靈活性。 適用于適配器只需要適配者對(duì)象的行為而不需要適配者對(duì)象的特定狀態(tài)的情況。Figure 20.6: Object Adapte

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論