適配器模式
當系統依賴的接口提供了需要的功能,但是接口簽名並不是完全匹配時,就可以使用適配器模式,將外部接口橋接到內部系統上。
public interface RemoteCallBackA {
void doCallBackA();
}
public interface RemoteCallBackB {
void doCallBackB();
}
public class BuzLogic {
public void doLogic(Object callBack) { //做完自身業務邏輯後回調外部接口
System.out.println("do business start");
System.out.println("do business end");
if (callBack instanceof RemoteCallBackA) {
((RemoteCallBackA) callBack).doCallBackA();
} else if (callBack instanceof RemoteCallBackB) {
((RemoteCallBackB) callBack).doCallBackB();
}
}
}
自己的業務BuzLogic需要回調2個外部系統的接口,但外部接口簽名不通用,只能通過instanceof來進行區分;當增加一個外部系統時,必然會修改BuzLogic的核心功能;違背開閉原則。設計的原則是封裝變化的點,這裏變化的點是外部系統簽名不同,因此可以使用適配器模式封裝這一變化。
public interface CallBackAdapter {
public void callBack(Object target);
public boolean supports(Object remoteInterface);
}
public class CallBackAdapterA implements CallBackAdapter {
public void callBack(Object target) {
RemoteCallBackA remoteCallBackA = (RemoteCallBackA)target;
remoteCallBackA.doCallBackA();
}
@Override
public boolean supports(Object remoteInterface) {
return remoteInterface instanceof RemoteCallBackA;
}
}
public class CallBackAdapterB implements CallBackAdapter {
@Override
public void callBack(Object target) {
RemoteCallBackB remoteCallBackA = (RemoteCallBackB)target;
remoteCallBackA.doCallBackB();
}
@Override
public boolean supports(Object remoteInterface) {
return remoteInterface instanceof RemoteCallBackB;
}
}
public class BuzLogic {
CallBackAdapter[] callBackAdapterArray = new CallBackAdapter[]{new CallBackAdapterA(),new CallBackAdapterB()};
public void doLogic(Object callBack) {
System.out.println("do business start");
System.out.println("do business end");
CallBackAdapter adapter = getCallBackAdapter(callBack);
adapter.callBack(callBack);
}
private CallBackAdapter getCallBackAdapter(Object callBack) {
for (CallBackAdapter adapter : callBackAdapterArray) {
if (adapter.supports(callBack)) {
return adapter;
}
}
return null;
}
}
之後如果要增加外部系統,只需要添加一個Adapter就可以了,無需修改doLogic代碼。
拋開具體代碼,這個模式帶給我們的啓發是通過繼承和循環替代if/else達到代碼的整潔。在擴展功能時由於使用了if/else需要修改業務邏輯,導致違背開閉原則,不便於橫向擴展 。適配器模式封裝這種變化消除if/else,把每個變化分支放到一個子類中去,在上面的例子中supports和callBack組成一個分支;然後通過父類將所有變化點組織起來,並通過for循環的方式去遍歷每個分支;當增加新的分支時,添加一個新的子類而無需修改for循環,達到對新增開發對修改封閉。這種編碼的思想應該牢記於心,當複雜業務邏輯使用if/else橫向擴展時,就應該通過設計模式封裝變化。
另外一種類適配器以MouseAdapter爲例,它實現了MouseListener, MouseWheelListener, MouseMotionListener這3個接口,併爲所有方法生成了一個空實現方便子類使用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.