Java設計模式之從[滑鼠介面][星際爭霸中的兵種行為]分析適配器(Adapter)模式

來源:互聯網
上載者:User

  適配器將一個類的介面轉換成客戶希望的另外一個介面。下面用三個例子來反映適配器的不同用途:

  情況一:

  我買了一個PS2介面的滑鼠,但是我的電腦沒有PS2的介面,僅有USB的介面。為了不浪費這個滑鼠,我跑到商店買了一個PS2到USB的轉接頭,這樣我就用上了PS2的滑鼠。USB轉接頭就是一個典型的適配器。

interface USBPort {    void connect();}interface PS2Port {    void connect();}class USBMouse implements USBPort {    public void connect(){        System.out.println("滑鼠串連上了USB連接埠!");    }}class PS22USBMouseAdapter implements USBPort{    private USBPort usbMouse;    public PS22USBMouseAdapter (USBPort usbPort){        usbMouse = usbPort;    }    public void connect(){        usbMouse.connect();    }}class Adapter1{    public static void main(String[] args) {        USBMouse mouse = new USBMouse();        mouse.connect();        USBPort adapter = new PS22USBMouseAdapter(mouse);        adapter.connect();    }}

  PS22USBMouseAdapter是一個PS2到USB介面的適配器,由於它最終輸出的是USB資訊,因此繼承了USBPort。我們最後執行個體化adapter時,它的類型是USBPort —— 設計模式就是如此,我們一般用對象的抽象來進行聲明和定義,而不是具體的類。PS22USBMouseAdapter實現了PS2介面向USB介面的轉變。

  情況二:

  星際爭霸中,人族的頂級兵種為戰鬥巡洋艦(Battlecruiser)。巡洋艦上有個技能叫做大和炮(Yamato gun)。

  假設我們在設計巡洋艦的時候,並沒有想到它可以裝載大和炮,那麼我們的巡洋艦類(Battlecruiser)中僅有一個attack方法。後來我們希望給巡洋艦增加一個大和炮的技能,但是我們又不想修改巡洋艦類的代碼,這個時候就可以用適配器來實現,此時的適配器可以理解成,我們在巡洋艦上裝一個轉換裝置,使得它可以安裝和發射大和炮。

class Battlecruiser{    public void attack(){        System.out.println("大和戰艦發起進攻!");    }}class YamatoAdapter extends Battlecruiser implements Yamato {    public void yamato(){        System.out.println("大和戰艦使用大和炮進行攻擊!");    }}interface Yamato{    void attack();    void yamato();}class Adapter2{    public static void main(String[] args) {        Yamato superBattlecruiser = new YamatoAdapter();         superBattlecruiser.attack();        superBattlecruiser.yamato();    }}

  注意,Battlecruiser類是我們一開始就設計好的。為了能給巡洋艦裝上大和炮,我們建立了一個Yamato介面,這個介面有原來巡洋艦的attack方法,並且還增加了一個yamato方法。最後,建立一個繼承於巡洋艦的類YamatoAdapter,在測試類別中用Yamato執行個體化一個巡洋艦,它既可以普通攻擊,又可以用大和炮進行攻擊。

  你可能會想,明明YamatoAdapter已經繼承了Battlecruiser,為何還要繼承Yamato介面?原因如之前所說,我們用“介面”來定義對象,而不是用具體的類。

  情況三:

  我需要設計星際爭霸人族兵種的一些抽象過程。如,所有兵種都要繼承於一個介面,這個介面有attack、stop、move等方法。這也就意味著,任何一個兵種類都要實現attack、stop、move這三個方法。

  這樣一來會有一個問題:並非所有的兵種都有attack、stop、move這3個行為。例如人族的醫學兵(Medic),她不具有attack行為(遊戲中她是無法攻擊敵人的);再例如人族的禿鷹戰車(Vulture,我們俗稱的布雷車),它可以埋蜘蛛雷。蜘蛛雷在敵人靠近的時候,它才會進行自爆攻擊。也就是說,蜘蛛雷不具有stop和move方法,只具有attack方法。

  可見,一旦介面的方法多了起來,我們為了實現它們得手工寫不少代碼,要是其中若干方法是我們該類不會用到的,我們不得不寫一個空方法。為了減少代碼編寫,這時,我們可以使用介面的適配器模式:

interface StarcraftSoldier{    void attack();    void stop();    void move();}abstract class SoldierAdapter implements StarcraftSoldier {    public void attack(){}    public void stop(){}    public void move(){}}class SpiderMine extends SoldierAdapter {    public void attack(){        System.out.println("蜘蛛雷發現敵人,進攻!");    }}class Adapter3{    public static void main(String[] args) {        new SpiderMine().attack();    }}

  介面的適配器SoldierAdapter為介面StarcraftSoldier的所有方法做了空實現,在我們建立SpiderMine時,繼承SoldierAdapter,就不必將介面中的所有方法都實現一次了。

  以上就是我所理解的適配器的用途,我把它理解成一個相容裝置,或者轉換裝置。若有牽強的地方,歡迎大家指出。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.