適配器模式刻坊,與我們傳統(tǒng)認(rèn)識里的ListView中使用的Adapter有些不一樣院促,但思想是共通的娜汁,通過適配器連接兩個毫無關(guān)聯(lián)的類嫂易。
適配器模式:
從實現(xiàn)方式上分為兩種,- 類適配器 - 對象適配器
這兩種的區(qū)別在于實現(xiàn)方式上的不同掐禁,一種采用繼承怜械,一種采用組合的方式。
另外從使用目的上來說傅事,也可以分為兩種缕允,- 特殊適配器 - 缺省適配器,這兩種的區(qū)別在于使用目的上的不同蹭越,一種為了復(fù)用原有的代碼并適配當(dāng)前的接口障本,一種為了提供缺省的實現(xiàn),避免子類需要實現(xiàn)不該實現(xiàn)的方法SimpleAdapter
响鹃。
場景:
場景通常情況下是驾霜,系統(tǒng)中有一套完整的類結(jié)構(gòu),而我們需要利用其中某一個類的功能(通俗點(diǎn)說可以說是方法)买置,但是我們的客戶端只認(rèn)識另外一個和這個類結(jié)構(gòu)不相關(guān)的接口寄悯,這時候就是適配器模式發(fā)揮的時候了,我們可以將這個現(xiàn)有的類與我們的目標(biāo)接口進(jìn)行適配堕义,最終獲得一個符合需要的接口并且包含待復(fù)用的類的功能的類猜旬。
比如我們在觀察者一章中就提到一個問題脆栋,就是說觀察者模式的一個缺點(diǎn),即如果一個現(xiàn)有的類沒有實現(xiàn)Observer接口洒擦,那么我們就無法將這個類作為觀察者加入到被觀察者的觀察者列表中了椿争,這實在太遺憾了。我們希望將HashMap這個類加到觀察者列表里熟嫩,在被觀察者產(chǎn)生變化時秦踪,假設(shè)我們要清空整個MAP。
類適配器:
public class HashMapObserverAdapter<K, V> extends HashMap<K, V> implements Observer{
public void update(Observable o, Object arg) {
//被觀察者變化時掸茅,清空Map
super.clear();
}
}
隨之而來帶來了新的問題:如果我們需要繼承別的類椅邓,由于單繼承,我們很難實現(xiàn)昧狮,很簡單的一個例子景馁,在一個應(yīng)用的網(wǎng)絡(luò)請求中我們通常需要分裝code,errorMsg等共有的屬性,以便處理逗鸣,如果此時無法再繼承其他類合住,這時候就需要通過組合實現(xiàn)對象適配器:
//我們繼承User,組合Observable.
public class ObservableUser extends User{
private Observable observable = new Observable();
public synchronized void addObserver(Observer o) {
observable.addObserver(o);
}
public synchronized void deleteObserver(Observer o) {
observable.deleteObserver(o);
}
public void notifyObservers() {
observable.notifyObservers();
}
public void notifyObservers(Object arg) {
observable.notifyObservers(arg);
}
public synchronized void deleteObservers() {
observable.deleteObservers();
}
protected synchronized void setChanged() {
observable.setChanged();
}
protected synchronized void clearChanged() {
observable.clearChanged();
}
public synchronized boolean hasChanged() {
return observable.hasChanged();
}
public synchronized int countObservers() {
return observable.countObservers();
}
}
們繼承User,而不是繼承Observable撒璧,這個原因剛才已經(jīng)說過了透葛,我們不能破壞項目中的繼承體系,所以現(xiàn)在可觀察的User(ObservableUser)依然處于我們實體的繼承體系中卿樱,另外如果想讓ObservableUser具有User的屬性僚害,則需要將User的屬性改為protected。
這下好了繁调,我們有了可觀察的User了贡珊。不過LZ早就說過,設(shè)計模式要活用涉馁,這里明顯不是最好的解決方案门岔。因為我們要是還有Person,Employee類都要具有可觀察的功能的話,那其實也相當(dāng)慘烤送,因為下面那些Observable的方法我們還要再復(fù)制一遍寒随。
//我們擴(kuò)展BaseEntity,適配出來一個可觀察的實體基類
public class BaseObservableEntity extends BaseEntity{
private Observable observable = new Observable();
public synchronized void addObserver(Observer o) {
observable.addObserver(o);
}
public synchronized void deleteObserver(Observer o) {
observable.deleteObserver(o);
}
public void notifyObservers() {
observable.notifyObservers();
}
public void notifyObservers(Object arg) {
observable.notifyObservers(arg);
}
public synchronized void deleteObservers() {
observable.deleteObservers();
}
protected synchronized void setChanged() {
observable.setChanged();
}
protected synchronized void clearChanged() {
observable.clearChanged();
}
public synchronized boolean hasChanged() {
return observable.hasChanged();
}
public synchronized int countObservers() {
return observable.countObservers();
}
}
這下好了,現(xiàn)在我們的User帮坚,Person妻往,Employee要是想具有可被觀察的功能,那就改去繼承我們適配好的BaseObservableEntity就好了试和,而且由于BaseObservableEntity繼承了BaseEntity讯泣,所以他們?nèi)齻€依然處于我們實體的繼承體系中,而且由于我們的BaseObservableEntity是新增的擴(kuò)展基類阅悍,所以不會對原來的繼承體系造成破壞好渠。對于缺省適配器昨稼,可以參考SimpleAdapter
的實現(xiàn)。