前言 : 個人理解, 適配的意思即爲, 把一個東西適當的改變一哈, 變爲可以配合另一個東西使用的能力, 適配器就是擁有這種能力的東西.
在 java 設計模式中, 適配器的意思也是相同的, 即把一個接口適配成另一種接口的樣子, 這裏所說的接口, 必須是擁有大體相同的功能, 或者是一個功能的不同實現, 否則適配的目的就顯得非常不單純了或者說根本無法適配.
適配器模式
JDK 曾經的某個版本中有對集合元素的處理接口 Enumeration, 如下 :
public interface Enumeration {
boolean hasMoreElement();
Object getNext();
}
假如有一個具體實現 :
public class ConcreteEnumeration implements Enumeration {
@Override
public boolean hasMoreElement() {
System.out.println("this is method hasMoreElement from Enumeration . ");
return true;
}
@Override
public Object getNext() {
System.out.println("this is method getNext from Enumeration . ");
return null;
}
}
一箇舊有服務中暴露出此接口 :
public class OldService {
public static Enumeration getEnumerator() {
return new ConcreteEnumeration();
}
}
後期 JDK 提供了新的集合服務接口 Iterator :
public interface Iterator {
boolean more();
Object next();
void remove();
}
一個具體實現 :
public class ConcreteIterator implements Iterator {
@Override
public boolean more() {
System.out.println("this is method more from Iterator . ");
return false;
}
@Override
public Object next() {
System.out.println("this is method next from Iterator . ");
return null;
}
@Override
public void remove() {
System.out.println("this is method remove from Iterator . ");
}
}
新的服務中開始使用新接口 :
public class NewService {
public static void processIterator(Iterator iterator) {
// TODO
}
}
那麼問題來了, 舊有服務還需要使用, 那麼舊有服務暴露出來的舊有接口我們還需要兼容使用, 如何處理 ?
public class Client {
public static void main(String[] args) {
// 編譯出錯, 不兼容舊接口, 不能使用舊服務
NewService.processIterator(OldService.getEnumerator());
}
}
於是適配器出現了, 來看看它是如何工作的 :
public class Adapter implements Iterator {
private Enumeration enumeration;
public Adapter(Enumeration enumeration) {
this.enumeration = enumeration;
}
@Override
public boolean more() {
return enumeration.hasMoreElement();
}
@Override
public Object next() {
return enumeration.getNext();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
分析 :
1.它實現了需要適配成的接口(Iterator)
2.它保有一個被適配的接口(Enumeration)
3.它實現要適配成的接口的方法
4.3中實現的方法裏時機調用的是被適配接口的方法
5.如果有新接口提供但是舊接口沒提供的方法, 可以拋出一個不支持的操作的異常.
這樣舊接口便被兼容到了新接口上.
來看看客戶端如何調用 :
public class Client {
public static void main(String[] args) {
NewService.processIterator(new Adapter(OldService.getEnumerator()));
}
}
如此簡單.
適配器模式的作用 :
- 系統需要使用現有的類,而這些類的接口不符合系統的接口
- 想要建立一個可以重用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作
- 兩個類所做的事情相同或相似,但是具有不同接口的時候
- 舊的系統開發的類已經實現了一些功能,但是客戶端卻只能以另外接口的形式訪問,但我們不希望手動更改原有類的時候
- 使用第三方組件,組件接口定義和自己定義的不同,不希望修改自己的接口,但是要使用第三方組件接口的功能