1. 程式人生 > >C++設計模式之介面卡(Adapter)模式

C++設計模式之介面卡(Adapter)模式

1. 標準定義
介面卡模式標準定義:將一個類的介面轉換成客戶希望的另外一個介面。Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。
2. 分析和說明
介面卡模式屬於結構型設計模式。適用性:你想使用一個已經存在的類,而它的介面不符合你的需求。你想建立一個可以複用的類,該類可以與其他不相關的類或不可預見的類(即那些介面可能不一定相容的類)協同工作。(僅適用於物件Adapter )你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的介面。物件介面卡可以適配它的父類介面。把一個類的介面變換成客戶端所期待的另一種介面,從而使原本因介面原因不匹配而無法一起工作的兩個類能夠一起工作。介面卡模式也叫變壓器模式,也叫包裝器(Wrapper)模式。
當一個類需要另一個類的方法,但是這兩個類併兼容。從實現原理上來看.達到這一目的的方法有兩種:一種是繼承,一種是物件組合。第一種方法中.從一個非一致性的類中派生一個新類,並增加新的方法使派生類與所需介面匹配;第二種方法中.在新類中包含最初的類.並建立方法來解釋新類中的呼叫.這兩種方法即人們通常所俗稱的類介面卡和物件介面卡。介面卡可以採用類的介面卡,也可以採用物件的介面卡。
介面卡(Adapter)模式結構包括的角色有目標(Target)角色、源(Adaptee)角色和介面卡(Adapter)角色。
目標(Target)角色:這就是所期待的介面,定義了客戶所期望的操作。目標(Target)角色可以是具體類或抽象類。該角色不可缺少。
源(Adaptee)角色:這是我們原有的產品,也是需要被適配的產品。這是我們原有的產品,也是需要被適配的產品:源(Adaptee)角色可以用介面、抽象類和具體類來實現。該角色不可缺少。
介面卡(Adapter)角色:介面卡角色是本模式的核心。Adapter對Adaptee介面與Target介面進行適配,介面卡把源介面轉換成目標介面,在Target目標角色與Adaptee源角色之間提供一種過渡,即把Adaptee源角色所提供的介面轉換為Target目標角色所提供的介面。介面卡(Adapter)角色必須是具體類。該角色不可缺少。
3.介面卡模式特點:
介面卡模式主要解決的問題就是我們要呼叫的介面型別,無法滿足我們新系統的使用需求,這時候,我們需要將舊系統的介面,通過介面卡進行轉配,達到支援新介面呼叫的目的。對於這樣的要求,我們通過介面卡就可以完成,當然如果有多個介面需要轉配,那麼我們就需要為每一個介面提供一個介面卡去完成轉換的工作。具體的呼叫過程,我們可以進行相應的封裝。達到比較通用的方式去呼叫介面卡,完成適配服務。
a.Adapter模式主要應用於“希望複用一些現存的類,但是介面又與複用環境要求不一致的情況”,在遺留程式碼複用、類庫遷移等方面非常有用。
b.Adapter模式有物件介面卡和類介面卡兩種形式的實現結構,但是類介面卡採用“多繼承”的實現方式,帶來了不良的高耦合,所以一般不推薦使用。物件介面卡採用“物件組合”的方式,更符合鬆耦合精神。在Adapter模式的兩種模式中,有一個很重要的概念就是介面繼承和實現繼承的區別和聯絡。介面繼承和實現繼承是面向物件領域的兩個重要的概念,介面繼承指的是通過繼承,子類獲得了父類的介面,而實現繼承指的是通過繼承子類獲得了父類的實現(並不統共介面)。在C++中的public繼承既是介面繼承又是實現繼承,因為子類在繼承了父類後既可以對外提供父類中的介面操作,又可以獲得父類的介面實現。當然我們可以通過一定的方式和技術模擬單獨的介面繼承和實現繼承,例如我們可以通過private繼承獲得實現繼承的效果(private繼承後,父類中的介面都變為private,當然只能是實現繼承了。),通過純抽象基類模擬介面繼承的效果,但是在C++中pure virtual function也可以提供預設實現,因此這是不純正的介面繼承,但是在Java中我們可以interface來獲得真正的介面繼承了。
4.適用場景:
系統需要使用現有的類,而此類的介面不符合系統的需要。
注:介面卡模式不適合在系統設計階段採用,沒有一個系統分析師會在做詳設的時候考慮使用介面卡模式,這個模式使用的主要場景是擴充套件應用中。系統擴充套件了,不符合原有設計的時候才考慮通過介面卡模式減少程式碼修改帶來的風險。
5.C++程式碼實現:
#include<iostream>
#include<string> 
using namespace std;
//介面卡基類 
class Target{
public:
Target()
{
//預設構造 
}
virtual void Request()
{
cout<<"普通的請求!"<<endl;
}
virtual ~Target()
{
cout<<"~Target!"<<endl;
}
};
// 與被Adapter物件提供不相容介面的類
//舊系統,新系統通過介面卡基類適配舊系統 
class Adaptee{
public:
Adaptee()
{
//預設構造 
}
~Adaptee()
{
cout<<"~Adaptee!"<<endl;
}
void SpecialRequest(string num)
{
cout <<"舊系統:這是Adaptee型別"<<num<<"請求!"<<endl;
}
};
// 進行Adaptee的類,採用聚合原有介面類的方式
//具體介面卡 物件模式 
class Adapter:public Target{
private:
Adaptee* pAdptee;
public:
Adapter(Adaptee* pAdaptee): pAdptee(pAdaptee)
{

}
Adapter()
{
//pAdptee=new Adaptee();
}
virtual void Request()
{
//cout << "具體介面卡:Adapter型別請求!"<<endl;
pAdptee->SpecialRequest("1");
}
virtual ~Adapter()
{
delete pAdptee;
pAdptee = NULL;
cout<<"~Adapter!"<<endl;
}
};
//類模式,介面卡類,通過public繼承獲得介面繼承的效果,通過private繼承獲得實現繼承的效果
class Adapter1:public Target,private Adaptee{
public:
   Adapter1()
{

}     
~Adapter1()
{

}
     virtual void Request()//實現Target定義的Request介面
     {
     this->SpecialRequest("2");
     }
};


int main(void)
{
//類模式Adapter
 Target* pTarget = new Adapter1();
pTarget->Request();

//物件模式Adapter1 
Target* pTarget1 = new Adapter();
   pTarget1->Request();
   
//物件模式Adapter2
Adaptee* adaptee = new Adaptee();
   Target* pTarget2= new Adapter(adaptee);
   pTarget2->Request();
   
   delete pTarget;
   delete pTarget1;
   delete pTarget2;
return 0;
}