一般,在代碼已經存在的狀況下編寫客戶端代碼(客戶端就是須要調用咱們代碼的對象),開發人員能夠採起模擬客戶端的方式調用咱們提供的接口對象。然而,客戶端代碼也可能與你的代碼單獨進行開發,這種狀況下,會發現雖然現有代碼提供了客戶端須要的服務,但被定義成不一樣的方法名。這時,咱們就須要採用適配器模式。適配器模式的意圖在於,使用不一樣接口的類所提供的服務爲客戶端提供它所須要的接口。java
適配器模式可分爲兩種:ide
(1)類適配器ui
(2)對象適配器this
類適配器:對象
當咱們適配現有代碼時,發現客戶端開發人員已經考慮到了這種情形,開發人員爲客戶端使用的服務提供了接口定義。以下:blog
public interface RequiredInterface { public void requiredMethod(); }
RequiredInterface接口定義了客戶端須要調用的服務方法requiredMethod,在ExsitingClass類中,則定義了usefulMethod方法,它是客戶端須要的服務實現。繼承
public class ExistingClass { public void usefulMethod() { System.out.println("useful method!!!"); } }
若要對ExistingClass進行適配,知足客戶端須要,則能夠建立一個NewClass類,繼承ExistingClass,同時繼承RequiredInterface接口,經過重寫requiredMethod方法將客戶端的請求委託給usefulMethod方法,以下:接口
public class NewClass extends ExistingClass implements RequiredInterface{ public void requiredMethod() { this.usefulMethod(); } }
圖1開發
圖1中的NewClass類就是類適配器的例子。該類的實例同時也是RequiredInterface的實例。換言之,NewClass類知足類客戶端的需求。it
當客戶端在接口中定義了它所期待當行爲時,就能夠使用類適配器,提供一個實現該接口的類。假若沒有定義客戶端的接口,則不能使用類適配器,此時必須使用對象適配器。在類適配器中,新的適配器類實現了定義的接口,同時繼承現有類。當你須要適配的方法並不是定義在接口中時,這種方法就不湊效類。此時咱們能夠建立一個對象適配器,使用委託而非繼承,以下圖所示:
上圖中的NewClass是對象適配器的一個例子,該類的實例也是RequiredClass的實例,換言之,NewClass知足了客戶端的須要。NewClass經過使用ExistingClass實例對象,能夠將ExistingClass類適配爲符合客戶端的須要。
public class RequiredClass { public void requiredMethod(){ } } public class NewClass extends RequiredClass { private ExistingClass existingClass = new ExistingClass(); @Override public void requiredMethod() { existingClass.usefulMethod(); } }
適配器模式能夠是咱們重用一個現有的類,以知足客戶端的須要。當客戶端經過接口表達其需求時,採用類適配器,建立一個實現該接口的類,同時繼承現有類。 當客戶端沒有指定它所須要的接口時,應採用對象適配器,建立一個類使用現有類的實例。若是咱們不須要(或者不能)重寫客戶端可能調用的方法時,這種方式可能存在必定的危險性。