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