從名字上就可以看出介面卡是為了針對介面不匹配的情況,而做出的相容方法,
假設我們有乙個已經存在的類adaptee,其中有一些已經存在並實現好的方法methoda。但是客戶不希望呼叫這個類,而是希望呼叫乙個特定的介面例如target介面。
於是如果想要呼叫adaptee.methoda()方法,建立乙個adapter類實現客戶要求的target介面,target介面中假設客戶希望呼叫callmethoda()方法來實現adaptee.methoda()方法功能。能夠想到的就是以下兩種方式:
讓adapter類實現target介面介面同時繼承adaptee類,這樣adapter類就繼承了adaptee.methoda(),在其callmethoda()中呼叫父類的methoda()方法即可。客戶新建adapter類物件,就可以通過target介面呼叫adapter.methoda()。
讓adapter類中持有乙個adaptee類的例項,在adapter類實現target介面的methoda()方法時,在其中呼叫adaptee例項的methoda()方法即可。
在上面的類的介面卡基礎上,只需要修改adapter和客戶類即可。
public
class
adapter
implements
target
@override
public
void
callmethoda()
@override
public
void
othermethod()
}
public
class
client
}
輸出結果也是一樣的
i am the methoda in adaptee
i am the othermethod in adapter
兩種模式各有利弊,類的介面卡模式已經繼承了adaptee類,就沒法再繼承其他的類,這時它的弊端,不過好處就是邏輯比較清晰,適合只適配單一的adaptee的情況。物件的介面卡模式則沒有繼承的限制,採用聚合的方式來適配待適配的類。個人個傾向於物件的介面卡模式這種介面卡方式,耦合性更低。
介面卡還有第三種模式,看起來和上面的兩種介面卡模式不太一樣,
對於乙個定義了較多方法的介面,我們實現該介面的時候,一來實現這麼多的方法很麻煩。二來有些方法我們並不需要,都實現了反而混淆了重點。
為了解決這個問題,就是用乙個抽象類繼承該介面,並在抽象類中使用空實現來實現介面中的方法。(也不一定,有些情況抽象類中會有介面中的方法的預設實現,而繼承它的子類中只需要完成其特有的一些方法,或者在原有方法的基礎上進行增加。例如android中的phonebase類,baseadapter類等)。
public
inte***ce
target
public
abstract
class
abstracttarget
implements
target
//可以留乙個b方法不實現,b還是抽象的,留給子類必須實現
@override
public
void
c()
@override
public
void
d()
@override
public
void
e()
@override
public
void
f()
}public
class
concretetarget
extends
abstracttarget
@override
public
void
a()
@override
public
void
c()
}
public
static
void
main(string args)
android中最常見的介面卡模式就屬於android中的adapter了,其應用融合了預設介面卡模式和物件的介面卡模式
抽象類baseadapter實現listadapter和spinneradapter兩個介面,而這兩個介面都是繼承自adapter介面,這兩個介面分別又定義了自己的方法
public
abstract
class
baseadapter
implements
listadapter, spinneradapter
不過baseadapter中並未實現介面中的全部方法
******adapter則繼承了baseadapter,並實現了所有沒實現的介面方法,有些baseadapter已經實現的方法,並沒有實現。
public
class
******adapter
extends
baseadapter
這裡就是上面的預設介面卡模式。
那麼物件的介面卡呢,
當我們使用******adapter時,例如:
listview.setadapter(new ******adapter(this, getdata(path),
android.r.layout.******_list_item_1, new string ,
newint ));
先看一下******adapter建構函式
public
******adapter(context context, list extends map> data,
int resource, string from, int to)
其中第2個引數是乙個map的佇列,對應每乙個list的item的資料,第3個引數則是展開這個item的view的layout資源的整形id。第4個引數from陣列是第2個引數的map的key,最後乙個引數to陣列則是from引數的每乙個key對應的資料放置在哪個元件裡。
在listview呼叫onmeasure確定元件尺寸時,就會呼叫到madapter.getcount(),呼叫這個******adapter的getcount()函式:
public
intgetcount()
public object getitem(int position)
間接呼叫之前建立******adapter時建構函式傳遞的data資料。
在繪製的時候,則會呼叫
madapter.getview(position, null, this)
獲取介面卡所適配的資料所對應的view來進行繪製。
所以這裡******adapter就是對data物件的物件介面卡模式,如果不使用介面卡,listview直接持有data資料當然也可以得到資料。但是listview使用adapter的精髓就是不需要去管資料是什麼,只需要建立不同的adapter,就可以做出不同效果,含有不同元件的listview。
Android設計模式(二十)介面卡模式
將乙個類的介面變換成客戶端所期待的另一種介面,從而使原本因介面不匹配而無法在一起工作的兩個類能夠在一起工作。角色說明 首先來說下物件介面卡模式的實現方式,就以電壓轉換為例子。現在我們需要定義乙個220v轉換成5v的介面 inte ce adapter被適配角色,一般是已存在的類,需要適配新的介面。生...
android中的介面卡模式
這是個人關於android中的介面卡模式的一點見解。android sdk本身已經抽象好adapter類,listview等顯示資料集的控制項在其具體的 中使用adapter的抽象函式,然後程式設計師繼承adapter,實現其中的抽象函式,通過這種方式把list 陣列或者其他型別的資料集以listv...
設計模式中的介面卡模式
將乙個類的介面轉換成客戶希望的另外乙個介面。adapter模式使得原本由於介面不相容而不能一起工作的那些類可以在一起工作。比如 現在有個手機要充電,手機是5v的介面,我要用電源是220v的powera介面去充電,即呼叫power的方法charge 然而charge 只提供220v電源,而我們還有個5...