1. 程式人生 > >設計模式(二)------介面卡模式

設計模式(二)------介面卡模式

介紹

介面卡模式(Adapter Pattern)是作為兩個不相容的介面之間的橋樑。這種型別的設計模式屬於結構型模式,它結合了兩個獨立介面的功能。

這種模式涉及到一個單一的類,該類負責加入獨立的或不相容的介面功能。舉個真實的例子,讀卡器是作為記憶體卡和筆記本之間的介面卡。您將記憶體卡插入讀卡器,再將讀卡器插入筆記本,這樣就可以通過筆記本來讀取記憶體卡。

分類

介面介面卡

示例一

舉一個現有的例子,比如你想把Enumeration適配成Iterator,此時必須要明白幾個基礎概念,或者說是明確你的適配後目標和被適配的物件。

  • 目標:Iterator;
  • 物件:Enumeration;

做法:定義一個介面卡,實現你的目標,組合被適配的物件。

package com.silence.mode.struct.adapter;

import java.util.Enumeration;
import java.util.Iterator;

public class EnumerationIteratorAdapter implements Iterator {

    Enumeration enumeration;

    public EnumerationIteratorAdapter(Enumeration enumeration) {
        this
.enumeration = enumeration; } public boolean hasNext() { return enumeration.hasMoreElements(); } public Object next() { return enumeration.nextElement(); } public void remove() { } }

示例二

大家可能都遇到過一種困擾,比如實現一個介面,而在這個眾多介面方法中我們只需要使用其中一兩個,一般的做法就是隻實現其中這一兩個業務邏輯,其他預設實現。但是這樣一來就會出現很多冗餘的方法,看起來太不協調,在一些主流的框架裡面都會出現一些AbstractXXX的預設實現某個或者某些介面,這些實現邏輯基本上符合我們這個示例二所講的實現方法。

再舉一個例子,比如一般Filter都會有如下幾個方法:

package com.silence.mode.struct.adapter.inter_face;

public interface AnyFilter {

    void init();

    void doFilter();

    void destroy();

}

一般情況下我們可能只需要實現其中的doFilter(),那麼我們就要在程式碼中冗餘其它兩個方法,但是如果此時我們建立一個AbstractXXX來預設實現一下其中的方法:

package com.silence.mode.struct.adapter.inter_face;

public class AbstractFilter implements AnyFilter {

    @Override
    public void init() {
        System.out.println("Default init!");
    }

    @Override
    public void doFilter() {
        System.out.println("Default doFilter!");
    }

    @Override
    public void destroy() {
        System.out.println("Default destroy!");
    }

}

這樣一來,後續開發人員只需要實現AbstractFilter中的doFilter(),而不需要實現其它兩個方法的業務邏輯即可完成我們的預期:

package com.silence.mode.struct.adapter.inter_face;

public class FilterImpl extends AbstractFilter {

    @Override
    public void doFilter() {
        System.out.println("FilterImpl doFilter!");
    }

}

物件介面卡

不知道大家經歷沒有經歷過這樣一個時期,就是插頭上面套個插頭,或者是三相轉兩相或者兩相轉三相的時代。當然現如今我們已經不需要這麼做了,我們擁有了插線板~,但是下面我舉得這個例子就是那個時代的一個寫照!

我有個冰箱,是三相插頭的,但是我牆上的插板只有一個兩相的插座,怎麼辦?

首先看看兩相插頭是如何工作的:

package com.silence.mode.struct.adapter.object;

public interface TwoPhasePlug {

    void workWithTwoPlug(int plugs);

}
package com.silence.mode.struct.adapter.object.impl;

import com.silence.mode.struct.adapter.object.TwoPhasePlug;

public class RoundHeadTwoPhasePlug implements TwoPhasePlug {

    @Override
    public void workWithTwoPlug(int plugs) {

        System.out.println("兩相圓插頭擁有" + plugs + "個插頭!");

    }

}

然後我有個三相插頭的電器:

package com.silence.mode.struct.adapter.object;

public class ThreePhasePlug {

    public void workWithThreePlug(int plugs) {

        System.out.println("三相圓插頭擁有" + plugs + "個插頭!");

    }

}

下面我就需要一個插頭轉換器:

package com.silence.mode.struct.adapter.object;

/**
 * Created by Silence on 2018/6/12.
 */
public class Three2TwoPlugAdapter implements TwoPhasePlug {

    private ThreePhasePlug threePhasePlug;

    public Three2TwoPlugAdapter(ThreePhasePlug threePhasePlug) {

        this.threePhasePlug = threePhasePlug;

    }

    @Override
    public void workWithTwoPlug(int plugs) {

        plugs = plugs - 1;
        System.out.println("三相->兩相轉換器!");

        threePhasePlug.workWithThreePlug(plugs);

    }

}

這個示例中使用了介面卡擁有源的一個例項的方式,也就是組合的方式詮釋了轉換器的實現原理,還有一種就是繼承的方式,由於設計模式一個很重要的思想就是多用組合少用繼承,因此我摒棄了最後一種方式也就是繼承的方式,也被稱為類介面卡。