06:介面卡模式
目錄
一、介紹
介面卡模式(Adapter Pattern)是作為兩個不相容的介面之間的橋樑。這種型別的設計模式屬於結構型模式,它結合了兩個獨立介面的功能。一般分為前兩種模式,第三種較為特殊。
1.1、物件介面卡模式
在這種介面卡模式中,介面卡容納一個它包裹的類的例項。在這種情況下,介面卡呼叫被包裹物件的物理實體。
物件介面卡”通過組合除了滿足“使用者期待介面”還降低了程式碼間的不良耦合。在工作中推薦使用“物件適配”。
1.2、類介面卡模式
這種介面卡模式下,介面卡繼承自已實現的類(一般多重繼承)。
當客戶在介面中定義了他期望的行為時,我們就可以應用介面卡模式,提供一個實現該介面的類,並且擴充套件已有的類,通過建立子類來實現適配。
1.3、預設介面卡模式
預設介面卡模式是一種特殊的介面卡模式,但這個介面卡是由一個抽象類實現
二、使用場景
1、當想使用一個已存在的類,而它的介面不符合需求時。
2、你想建立一個可複用的類,該類可以與其他不相關的類或不可預見的類協同工作。
3、你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的介面,物件介面卡可以適配它的父介面。
三、要點
3.1、物件介面卡
1、有的時候,你會發現,去構造一個 Adaptee 型別的物件不是很容易。
2、當 Adaptee 中新增新的抽象方法時,Adapter 類不需要做任何調整,也能正確的進行動作。
3、可以使用多型的方式在 Adapter 類中呼叫 Adaptee 類子類的方法。
由於物件介面卡的耦合度比較低,所以在很多的書中都建議使用物件介面卡。在我們實際專案中,也是如此,能使用物件組合的方式,就不使用多繼承的方式。
3.2、類介面卡
1、由於 Adapter 直接繼承自 Adaptee 類,所以,在 Adapter 類中可以對 Adaptee 類的方法進行重定義。
2、如果在 Adaptee 中添加了一個抽象方法,那麼 Adapter 也要進行相應的改動,這樣就帶來高耦合。
3、如果 Adaptee 還有其它子類,而在 Adapter 中想呼叫 Adaptee 其它子類的方法時,使用類介面卡是無法做到的。
四、樣例
4.1、物件介面卡樣例
// 物件介面卡樣例
#include<iostream>
using namespace std;
// "ITarget":目標介面
class Target
{
public:
// Methods
virtual void Request(){};
};
// "Adaptee":適配者
class Adaptee
{
public:
// Methods
void SpecificRequest()
{
cout << "Called SpecificRequest()" << endl;
}
};
// "Adapter":介面卡
class Adapter : public Target
{
private:
Adaptee *adaptee;
public:
Adapter()
{
adaptee = new Adaptee();
}
// Implements ITarget interface
void Request()
{
// Possibly do some data manipulation
// and then call SpecificRequest
adaptee->SpecificRequest();
}
};
int main()
{
// Create adapter and place a request
Target *t = new Adapter();
t->Request();
return 0;
}
4.2、類介面卡模式樣例
// 類介面卡Demo
#include<iostream>
using namespace std;
// "ITarget"
class Target
{
public:
// Methods
virtual void Request(){};
};
// "Adaptee"
class Adaptee
{
public:
// Methods
void SpecificRequest()
{
cout << "Called SpecificRequest()" << endl;
}
};
// "Adapter"
class Adapter : public Adaptee, public Target
{
public:
// Implements ITarget interface
void Request()
{
// Possibly do some data manipulation
// and then call SpecificRequest
this->SpecificRequest();
}
};
int main()
{
// Create adapter and place a request
Target *t = new Adapter();
t->Request();
return 0;
}
4.3、預設介面卡模式樣例
// 預設介面卡模式
#include<iostream>
using namespace std;
class Target {
public:
virtual void f1(){};
virtual void f2(){};
virtual void f3(){};
};
class DefaultAdapter : public Target
{
public:
void f1() {
}
void f2() {
}
void f3() {
}
};
class MyInteresting :public DefaultAdapter
{
public:
void f3(){
cout << "呵呵,我就對f3()方法感興趣,別的不管了!" << endl;
}
};
int main()
{
// Create adapter and place a request
Target *t = new MyInteresting();
t->f3(); // 呵呵,我就對f3()方法感興趣,別的不管了!
return 0;
}
五、優缺點
優點
1、可以讓任何兩個沒有關聯的類一起執行
2、提高了類的複用
3、增加了類的透明度
4、靈活性好
缺點
過多地使用介面卡,會讓系統非常零亂,不利於整體把控。