1. 適配器模式簡(jiǎn)介
適配器模式(Adapter):將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
適用場(chǎng)景: 1、已經(jīng)存在的類的接口不符合我們的需求; 2、創(chuàng)建一個(gè)可以復(fù)用的類,使得該類可以與其他不相關(guān)的類或不可預(yù)見(jiàn)的類(即那些接口可能不一定兼容的類)協(xié)同工作;
3、在不對(duì)每一個(gè)都進(jìn)行子類化以匹配它們的接口的情況下,使用一些已經(jīng)存在的子類。
其實(shí)現(xiàn)方式主要有兩種:
1.類的適配器模式(采用繼承實(shí)現(xiàn))
2.對(duì)象適配器(采用對(duì)象組合方式實(shí)現(xiàn))
2. 類適配器
我們生活中常常聽(tīng)到的是電源適配器,它是用于電流變換(整流)的設(shè)備。適配器的存在,就是為了將已存在的東西(接口)轉(zhuǎn)換成適合我們的需要、能被我們所利用。在現(xiàn)實(shí)生活中,適配器更多的是作為一個(gè)中間層來(lái)實(shí)現(xiàn)這種轉(zhuǎn)換作用。
其中: Target — 定義Client使用的與特定領(lǐng)域相關(guān)的接口。 Client — 與符合Target接口的對(duì)象協(xié)同。 Adaptee — 定義一個(gè)已經(jīng)存在的接口,這個(gè)接口需要適配。 Adapter — 對(duì)Adaptee的接口與Target接口進(jìn)行適配
在上面的通用類圖中,Cient 類最終面對(duì)的是 Target 接口(或抽象類),它只能夠使用符合這一目標(biāo)標(biāo)準(zhǔn)的子類;而 Adaptee 類則是被適配的對(duì)象(也稱 源角色),因?yàn)樗瑂pecific (特殊的)操作、功能等,所以我們想要在自己的系統(tǒng)中使用它,將其轉(zhuǎn)換成符合我們標(biāo)準(zhǔn)的類,使得 Client 類可以在透明的情況下任意選擇使用 ConcreteTarget 類或是具有特殊功能的 Adatee 類。
代碼實(shí)現(xiàn)如下:
-
- class Adaptee {
- public void specificRequest() {
- System.out.println("被適配類具有 特殊功能...");
- }
- }
-
-
-
- interface Target {
- public void request();
- }
-
-
- class ConcreteTarget implements Target {
- public void request() {
- System.out.println("普通類 具有 普通功能...");
- }
- }
-
-
-
- class Adapter extends Adaptee implements Target{
- public void request() {
- super.specificRequest();
- }
- }
-
-
-
- public class Client {
- public static void main(String[] args) {
-
- Target concreteTarget = new ConcreteTarget();
- concreteTarget.request();
-
-
- Target adapter = new Adapter();
- adapter.request();
- }
- }
測(cè)試結(jié)果: 普通類 具有 普通功能... 被適配類具有 特殊功能...
上面這種實(shí)現(xiàn)的適配器稱為類適配器,因?yàn)?Adapter 類既繼承了 Adaptee (被適配類),也實(shí)現(xiàn)了 Target 接口(因?yàn)?Java 不支持多繼承,所以這樣來(lái)實(shí)現(xiàn)),在 Client 類中我們可以根據(jù)需要選擇并創(chuàng)建任一種符合需求的子類,來(lái)實(shí)現(xiàn)具體功能。
3. 對(duì)象適配器
另外一種適配器模式是對(duì)象適配器,它不是使用多繼承或繼承再實(shí)現(xiàn)的方式,而是使用直接關(guān)聯(lián),或者稱為委托的方式,類圖如下:
代碼實(shí)現(xiàn)如下:
-
- class Adapter implements Target{
-
- private Adaptee adaptee;
-
-
- public Adapter (Adaptee adaptee) {
- this.adaptee = adaptee;
- }
-
- public void request() {
-
- this.adaptee.specificRequest();
- }
- }
-
-
-
- public class Client {
- public static void main(String[] args) {
-
- Target concreteTarget = new ConcreteTarget();
- concreteTarget.request();
-
-
-
- Target adapter = new Adapter(new Adaptee());
- adapter.request();
- }
- }
測(cè)試結(jié)果與上面的一致。從類圖中我們也知道需要修改的只不過(guò)就是 Adapter 類的內(nèi)部結(jié)構(gòu),即 Adapter 自身必須先擁有一個(gè)被適配類的對(duì)象,再把具體的特殊功能委托給這個(gè)對(duì)象來(lái)實(shí)現(xiàn)。使用對(duì)象適配器模式,可以使得 Adapter 類(適配類)根據(jù)傳入的 Adaptee 對(duì)象達(dá)到適配多個(gè)不同被適配類的功能,當(dāng)然,此時(shí)我們可以為多個(gè)被適配類提取出一個(gè)接口或抽象類。這樣看起來(lái)的話,似乎對(duì)象適配器模式更加靈活一點(diǎn)。
4. 小結(jié)
1、適配器模式也是一種包裝模式,與之前的 Decorator 裝飾模式同樣具有包裝的功能;此外,對(duì)象適配器模式還具有顯式委托的意思在里面(其實(shí)類適配器也有這種意思,只不過(guò)比較隱含而已),那么我在認(rèn)為它與 Proxy 代理模式也有點(diǎn)類似;
2、從上面一點(diǎn)對(duì)比來(lái)看, Decorator 、 Proxy、 Adapter 在實(shí)現(xiàn)了自身的最主要目的(這個(gè)得看各個(gè)模式的最初動(dòng)機(jī)、描述)之外,都可以在包裝的前后進(jìn)行額外的、特殊的功能上的增減,因?yàn)槲艺J(rèn)為它們都有委托的實(shí)現(xiàn)意思在里面;
3、我所看的書(shū)中說(shuō)適配器模式不適合在詳細(xì)設(shè)計(jì)階段使用它,它是一種補(bǔ)償模式,專用來(lái)在系統(tǒng)后期擴(kuò)展、修改時(shí)所用。
|