開發之路(設計模式七:適配器模式)

你眼中的適配器是什麼樣子的呢?在設計模式中也有模式叫適配器模式,一塊兒來看看吧。

適配器是什麼這不須要做者我多解釋把,打個比方,在國內用的是220V的電器,但國外有些國家是110V甚至240V的也有等等,國內的充電線就不能直接插國外的插座了,這時候就須要一個適配器作電源轉換,是的,在設計模式中也有這麼一個模式與其相似,也是個頗有用的模式。編程

下面我作了幾個配圖來理解設計模式。設計模式

假設已有一個系統,此時它須要更新,你但願它能和新的廠商類庫搭配使用,可是這個新廠商設計出來的接口,與原系統的接口不同。因此二者不能直接匹配。
圖片描述ide

若重構原來的代碼可能會很是麻煩,並且又不能去改變廠商的代碼,怎麼辦呢?這是你能夠寫一個類,將新廠商接口轉換爲你所期待的接口。
圖片描述測試

那麼這個適配器就比如一箇中間人,它將客戶所發送的請求轉換成廠商類可以理解的請求。
圖片描述this

直接放一個例子,假如一隻火雞想要「冒充」成鴨子怎麼作呢?
代碼以下:spa

這是鴨子接口設計

package duck_Interface;

/**
 * 適配器模式:就比如在中國的電器若要在美國的插座上使用,就必須使用適配器, 
 * 適配器就至關於一箇中間層,將兩個本來不能相互溝通的東西鏈接在一塊兒
 * 
 * @author Joy
 * 
 */
public interface Duck {
    public void quack();

    public void fly();
}

綠頭鴨是鴨子的子類code

package duck_Implements;

import duck_Interface.Duck;

public class MallardDuck implements Duck {
    /**
     * 綠頭鴨
     */
    @Override
    public void quack() {
        System.out.println("綠頭鴨叫:呱呱呱");

    }

    @Override
    public void fly() {
        System.out.println("我在飛");
    }
}

這是一隻火雞(接口)對象

package duck_Interface;

/**
 * 火雞接口
 * 
 * @author Joy
 * 
 */
public interface Turkey {
    // 火雞隻會咯咯咯叫
    public void gobble();

    // 火雞會飛,但飛不遠
    public void fly();
}

這是火雞的一個具體實現繼承

package duck_Implements;

import duck_Interface.Turkey;

public class WildTurkey implements Turkey {
    /**
     * 火雞類的實現
     */

    @Override
    public void gobble() {
        System.out.println("火雞叫:咯咯咯");
    }

    @Override
    public void fly() {
        System.out.println("我會飛,但飛不高");
    }
}

很顯然二者一開始不能直接匹配,這裏寫一個火雞適配器

package Adapter;

import duck_Interface.Duck;
import duck_Interface.Turkey;

/**
 * 火雞的適配器
 * 
 * @author Joy
 * 
 */
// 先要實現想要轉換的類型接口,(火雞但願和綠頭鴨交流)
// 火雞:被適配者,鴨子:適配者
// 這裏火雞要實現鴨子接口
public class TurkeyAdapter implements Duck {
    Turkey turkey;

    // 須要取得適配的對象引用
    // 利用構造器取得這個引用
    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    @Override
    public void quack() {
        // 如今咱們須要實現火雞裏的叫的方法
        // 很簡單隻需直接引用
        turkey.gobble();
    }

    /**
     * 這裏因爲火雞的飛行距離短,鴨子飛行距離長, 爲二者飛行可以對應, 這裏得屢次調用火雞飛行方法,至關於火雞5次飛行的距離等於一次鴨子飛行的距離。。
     */
    @Override
    public void fly() {
        for (int i = 0; i < 5; i++) {
            turkey.fly();
        }
    }
}

測試類

package TestMain;

import Adapter.TurkeyAdapter;
import duck_Implements.MallardDuck;
import duck_Implements.WildTurkey;
import duck_Interface.Duck;

public class DuckTestDrive {
    // 取得一隻鴨子
    public static void testDuck(Duck duck) {
        duck.quack();
        duck.fly();
    }

    public static void main(String[] args) {
        // 建立好一隻鴨子和火雞
        MallardDuck duck = new MallardDuck();
        WildTurkey turkey = new WildTurkey();
        // 而後將火雞「包裝」進火雞適配器中,讓它看上起像只鴨子
        Duck turkeyAdapter = new TurkeyAdapter(turkey);
        System.out.println("這隻火雞說~~~~~");
        turkey.gobble();
        turkey.fly();
        System.out.println("\n這隻鴨子說a~~~~~");
        testDuck(duck);
        // 試着傳入一個僞裝是鴨子的火雞對象
        System.out.println("\n火雞適配器說~~~~~");
        /**
         * testDuck()方法不知道這是一隻僞裝鴨子的火雞 turkey調用叫的方法是「咯咯咯」
         * 而fly方法調用了5次,就爲了讓火雞僞裝成鴨子同樣飛的遠
         */
        testDuck(turkeyAdapter);

    }
}

效果圖
圖片描述

TurkeyAdapter裏的quack方法被調用,適配器咯咯咯的叫,而後fly方法被調用,適配器執行了5次飛行操做,而在testDuck(Duck duck)它還覺得參數duck真的是一鴨子,實際上是隻僞裝鴨子的火雞(turkeyAdapter)。

讓咱們再看看各部分之間的關係。
圖片描述

客戶使用適配器的過程以下:
一、客戶經過目標接口調用適配器的方法對適配器發出請求。
二、適配器(鴨子)使用被適配器(火雞)接口把請求轉換成被適配器的一個或多個調用接口。
三、客戶接收到調用的結果,但並未察覺這一切是適配器再起轉換做用。

定義適配器模式:將一個類的接口,轉換成客戶期待的另外一個接口。適配器讓本來接口不兼容的類能夠合做無間。

注:細分適配器類型是有兩種的,對象適配器和類適配器,前面的火雞例子是對象適配器,而「類」適配器則須要多重繼承才能實現,而Java中是不被容許的,這裏就不講述。

感謝你看到這裏,適配器模式到這裏就結束了,本人文筆隨便,如有不足或錯誤之處望給予指點,90度彎腰~~~很快我會發佈下一個設計模式的內容,生命不息,編程不止!

參考書籍:《Head First 設計模式》
相關文章
相關標籤/搜索