java設計模式學習筆記--介面卡模式
1、什麼是介面卡模式
介面卡模式:將一個類的介面,轉換成客戶端 期望的另一個介面。介面卡讓原本介面不相容的類可以合作無間。
這個模式可以通過建立介面卡進行介面轉換,讓不相容的介面變成相容。可以讓客戶端從從實現的介面解耦,如果在一段時間後,想要改變介面,介面卡可以將改變的部分封裝起來,客戶端就不必為了應對不同的介面而每次跟著改變。
2. 介面卡模式的結構
請先看類圖:
(物件介面卡)
(類介面卡)
他有如下幾個角色:
目標角色(Target):這是所期待得到介面
源角色(Adaptee):這是需要適配的介面
介面卡角色(Adaper):這是本模式的核心類。介面卡把源介面轉換成目標介面
下面請看程式碼分析:
類介面卡:
目標角色(Target):
//目標角色(Target)
public interface Target {
void specificMethod();
}
源角色(Adaptee):
//源角色(Adaptee)
public class Adaptee {
public void adapteeMethod(){};
}
介面卡角色(Adaper):
//介面卡角色(Adapter)
public class Adapter extends Adaptee implements Target{
/**
* 由於源類Adaptee沒有方法specificMethod()
* 因此介面卡補充上這個方法
*/
@Override
public void specificMethod() {
//do something
}
}
這就是一個簡單的類介面卡模式的案例,下面演示一個實際問題:
我們都知道,如果要用java自帶的方式實現一個觀察者模式,那麼觀察者就必須要實現Observer介面,那麼如果現在要將 HashMap作為觀察者應該怎麼辦哪?
這時候就可以用到介面卡了:
public class HashMapAdapter extends HashMap implements Observer {
@Override
public void update(Observable o, Object arg) {
//當觀察者狀態改變時
super.clear();
}
}
我們先寫一個HashMapAdapter 的介面卡角色,然後使其繼承HashMap,並實現Observer介面,這樣就成為了一個HashMap的觀察者。當被觀察者狀態改變時,就清空HashMap。
看完了類介面卡,然後我們來看一下物件介面卡吧:
目標角色(Target):
//目標角色(Target)
public interface Target {
void specificMethod();
}
源角色(Adaptee):
//源角色(Adaptee)
public class Adaptee {
public void adapteeMethod(){};
}
目標角色和源角色都未變,改變的是介面卡角色:
介面卡角色(Adaper):
public class Adapter{
private Adaptee adaptee ;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
/**
* 源類Adaptee有方法adapeeMethod
* 因此介面卡類直接委派即可
*/
public void adapeeMethod(){
this.adaptee.adapteeMethod();
}
/**
* 源類Adaptee沒有方法specificMethod
* 因此由介面卡類需要補充此方法
*/
public void specificMethod(){
// do something
}
}
可以看到,在這裡,我們用了組合的模式,而在類介面卡裡,我們使用的是繼承的模式。
3. 兩種方式的比較
對於這兩種方式的比較,我想用一段有趣的對話來說明:
4. 預設適配模式
預設適配模式為一個介面提供預設實現,這樣子型別就可以從這個預設實現進行擴充套件。從而不必從原來的介面進行擴充套件。
預設介面卡的作用:當我們的介面設計得過大,而子類不需要實現某些方法時(由於java中類必須實現介面中的所有方法),就會用到預設介面卡模式。
public interface People {
public void say();
public void eat();
public void walk();
}
public class DefaultAdapter implements People {
@Override
public void say() {
}
@Override
public void eat() {
}
@Override
public void walk() {
}
}
public class Child extends DefaultAdapter {
public void say(){
System.out.println("ya ya");
};
public void eat(){
System.out.println("ba ji ba ji");
};
}
在這裡,有一個People的介面,定義了三個方法 eat(), say(), walk(),現在有一個小孩子,由於小孩子是一個人,所以需要實現People介面,但是小孩子還不會走路,所以,這時候就需要預設介面卡,用來覆蓋不需要的方法,而子類只需要繼承介面卡就行了。
5.結束語
最後,我們應該明確的一點就是:介面卡模式是補救措施,所以在系統設計過程中不應該使用這個設計模式,這個模式只是在你無可奈何時的補救方式。