適配器模式主要解決是類與類之間接口不兼容情況,比如你又一個三口插座需要插入一個兩口插孔這個時候就需要適配器來做處理。適配器模式有兩種:類適配器、對象適配器、接口適配器。
類適配器模式
當我們要訪問的接口A中沒有我們想要的方法 ,卻在另一個接口B中發現了合適的方法,我們又不能改變訪問接口A,在這種情況下,我們可以定義一個適配器p來進行中轉,這個適配器p要實現我們訪問的接口A,這樣我們就能繼續訪問當前接口A中的方法(雖然它目前不是我們的菜),然后再繼承接口B的實現類BB,這樣我們可以在適配器P中訪問接口B的方法了,這時我們在適配器P中的接口A方法中直接引用BB中的合適方法,這樣就完成了一個簡單的類適配器。
class Test{
public interface Ps2 {
void isPs2();
}
public interface Usb {
void isUsb();
}
public class Usber implements Usb {
@Override
public void isUsb() {
System.out.println("USB口");
}
}
public class Adapter extends Usber implements Ps2 {
@Override
public void isPs2() {
isUsb();
}
}
public class Clienter {
public static void main(String[] args) {
Ps2 p = new Adapter();
p.isPs2();
}
}
}
對象適配器模式
與上面的類似,但是adapter略有不同,但是類適配器模式是通過繼承來獲取方法,而對象適配器模式是通過構造器傳來一個對象從而獲取方法。
public class Adapter implements Ps2 {
private Usb usb;
public Adapter(Usb usb){
this.usb = usb;
}
@Override
public void isPs2() {
usb.isUsb();
}
}
接口適配器模式
當存在這樣一個接口,其中定義了N多的方法,而我們現在卻只想使用其中的一個到幾個方法,如果我們直接實現接口,那么我們要對所有的方法進行實現,哪怕我們僅僅是對不需要的方法進行置空(只寫一對大括號,不做具體方法實現)也會導致這個類變得臃腫,調用也不方便,這時我們可以使用一個抽象類作為中間件,即適配器,用這個抽象類實現接口,而在抽象類中所有的方法都進行置空,那么我們在創建抽象類的繼承類,而且重寫我們需要使用的那幾個方法即可。
例子
比如安卓中ListView中的設計BaseAdapter其實實現的接口很多,但是你繼承BaseAdapter確只是實現四個方法,其他由BaseAdapter進行整合,這就是接口適配器。
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public boolean hasStableIds() {
return false;
}
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
/**
* Notifies the attached observers that the underlying data has been changed
* and any View reflecting the data set should refresh itself.
*/
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
/**
* Notifies the attached observers that the underlying data is no longer valid
* or available. Once invoked this adapter is no longer valid and should
* not report further data set changes.
*/
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled(int position) {
return true;
}
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent);
}
public int getItemViewType(int position) {
return 0;
}
public int getViewTypeCount() {
return 1;
}
public boolean isEmpty() {
return getCount() == 0;
}
}
總結
在軟件工程中,適配器模式是一種軟件設計模式,它允許現有類的接口作為另一個接口使用。它通常用于使現有類與其他類協同工作而不修改源代碼。
優勢
- 將目標類和適配者類解耦
- 增加了類的透明性和復用性,將具體的實現封裝在適配者類中,對于客戶端類來說是透明的,而且提高了適配者的復用性
- 靈活性和擴展性都非常好,符合開閉原則
缺點
過多地使用適配器,會讓系統非常零亂,不易整體進行把握。比如,明明看到調用的是 A 接口,其實內部被適配成了 B 接口的實現,一個系統如果太多出現這種情況,無異于一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。
對于類適配器而言,由于 JAVA 至多繼承一個類,所以至多只能適配一個適配者類,而且目標類必須是抽象類