適配器模式----將一個(gè)類的接口,轉(zhuǎn)換成客戶期望的另一個(gè)接口蛋铆。適配器讓原本接口不兼容的類可以合作無間
適配器模式就如它的名字一樣馋评,簡(jiǎn)單來說就是給舊的類或者對(duì)象套上一層新的殼子,并創(chuàng)建現(xiàn)在需要調(diào)用的函數(shù)刺啦,在函數(shù)體里面復(fù)用舊的函數(shù)或加些新的業(yè)務(wù)邏輯留特,以滿足調(diào)用者的需要。
最直接的也是最常見的就是對(duì)象適配器
一玛瘸、對(duì)象適配器
對(duì)象適配器持有被適配者的實(shí)例蜕青,并實(shí)現(xiàn)了目標(biāo)接口。
實(shí)例:迭代器與枚舉器
早期Java集合類型都實(shí)現(xiàn)了一個(gè)名為elements()的方法糊渊。該方法返回一個(gè)Enumeration枚舉右核。這個(gè)Enumeration接口可以逐一遍歷集合中的每一個(gè)元素,而無需知道它們?cè)诩蟽?nèi)是如何被管理的:
當(dāng)Sun推出更新后的集合類時(shí)渺绒,開始使用了Iterator迭代器接口蒙兰,這個(gè)接口與枚舉接口的唯一區(qū)別是多了remove()方法:
在實(shí)際開發(fā)過程中常常會(huì)面對(duì)已有的代碼,這些遺留的代碼使用老方法處理芒篷,但現(xiàn)在我們希望使用新的方法來實(shí)現(xiàn)相同的功能搜变,這個(gè)時(shí)候就可以使用適配器模式。如上述我們希望使用迭代器來完成之前枚舉所做的事情可以這樣寫:
public class EnumerationIterator implements Iterator {
Enumeration enum;
public EnumerationIterator (Enumeration enum) {
this.enum = enum;
}
public boolean hasNext() {
return enum.hasMoreElements();
}
public Object next() {
return enum.nextElement();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
在這個(gè)類中针炉,該類持有Enumeration實(shí)例挠他,并實(shí)現(xiàn)了Iterator的接口,在Iterator的各個(gè)接口中完成了向Enumeration方法的轉(zhuǎn)變篡帕。
throw new UnsupportedOperationException() 是因?yàn)槊杜e并不支持對(duì)數(shù)據(jù)的修改殖侵,所以適配器無法實(shí)現(xiàn)有實(shí)際功能的remove方法,這種情況下拋出UnsupportedOperationException()異常
二镰烧、類適配器
類適配器與對(duì)象適配器的唯一區(qū)別在于類適配器同時(shí)繼承被適配者和目標(biāo)類拢军,然后在內(nèi)部重寫目標(biāo)類方法,實(shí)現(xiàn)適配怔鳖。
對(duì)象適配器采用組合方式將請(qǐng)求傳給被適配者茉唉,類適配器采用繼承的形式統(tǒng)一目標(biāo)類和被繼承者。
三、衍生
在實(shí)際應(yīng)用中度陆,代碼并不一定需要嚴(yán)格遵守上面所列出的適配器的規(guī)則艾凯,可以根據(jù)實(shí)際情況來變通。
如Android開發(fā)中的RecyclerView的Adapter懂傀,它實(shí)現(xiàn)了數(shù)據(jù)與視圖的綁定趾诗,或者說將數(shù)據(jù)適配給了視圖。
在使用Adapter的時(shí)候我們通常有兩步要做:
① 繼承Adapter并實(shí)現(xiàn)自己的Adapter
② 實(shí)現(xiàn)自己的viewHolder
這個(gè)適配器與對(duì)象適配器有些類似,盡管它既沒有包含被適配的對(duì)象,也沒有實(shí)現(xiàn)目標(biāo)接口忆家,但如果我們把它常常會(huì)包含的數(shù)據(jù)對(duì)象當(dāng)作被適配的對(duì)象染突,把繼承自父類的方法作為目標(biāo)接口的話就很好理解了。
這么一來,也就是說適配器模式其實(shí)不僅只適用于對(duì)舊方法的適配,也常常用于將數(shù)據(jù)適配給視圖。
參考
- 《Head First 設(shè)計(jì)模式》