C++ 設計模式 - 轉接器模式 Adapter Pattern

當你旅行時,面對世界各地形形色色的插座,每個國家的插座形狀和電壓都可能不一樣,而你只帶了一台手機充電器。如果沒有一個合適的插頭轉接器,你的電子裝置將無法使用,例如台灣手機充電器帶去歐洲不能直接使用,接上了轉接頭就可以使用了。這個轉接器的角色就像是軟體開發中的轉接器模式 Adapter Pattern。在軟體開發中,我們經常需要整合不同的系統或使用第三方函式庫。但有時這些系統或函式庫的介面與我們的程式碼不相容。轉接器模式它的功能在於讓兩個原本不相容的介面協同工作,讓你可以在不更改既有程式碼的情況下,輕鬆地整合不同的系統或類別。

什麼是轉接器模式?

轉接器模式是一種結構型設計模式,它將原本介面不相容而不能一起工作的類能夠協同工作。簡單來說,轉接器就像是一個轉換器,將一個類的介面轉換成客戶端所期望的另一種介面。

這種模式讓原本不相容的類可以一起工作,而無需修改它們的原始碼。它在我們需要使用一個現有的類,但是其介面與我們的需求不匹配時特別有用。

轉接器模式通常用於解決因現有程式碼無法修改或類別不相容而導致的整合問題。加入轉接器後,我們可以在不更改既有類別的情況下,實現介面的一致性,達到程式碼的複用性和擴展性。

轉接器模式通常包含以下角色:

  1. 目標介面(Target):客戶端所期望的介面。
  2. 轉接者(Adaptee):需要被轉接的類,它有著不相容的介面。
  3. 轉接器(Adapter):將轉接者的介面轉換為目標介面的類別。

轉接器模式在JSON到XML轉換中的應用

讓我們用一個例子來理解轉接器模式:JSON到XML的資料格式轉換。

假設你正在開發一個系統,這個系統需要處理XML格式的資料。但是你發現有一個非常好用的第三方函式庫,可以提供你所需的所有資料,唯一的問題是這個函式庫輸出的是JSON格式。這時就可以使用轉接器模式幫助我們解決這個問題。

讓我們用程式碼來模擬這個場景:

首先我們定義目標介面(XML資料提供者),

1
2
3
4
class XMLData {
public:
virtual std::string getXMLData() = 0;
};

然後我們有一個現有的類(JSON資料提供者),它的介面與目標介面不相容,

1
2
3
4
5
6
class JSONData {
public:
std::string getJSONData() {
return "{\"name\": \"John\", \"age\": 30}";
}
};

現在我們建立一個轉接器類,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class JSONToXMLAdapter : public XMLData {
private:
JSONData* jsonData;

public:
JSONToXMLAdapter(JSONData* data) : jsonData(data) {}

std::string getXMLData() override {
std::string jsonData = this->jsonData->getJSONData();
// 實際的JSON到XML的轉換邏輯
// 為了簡化,我們只做一個模擬的轉換
std::string xmlData = "<person><name>John</name><age>30</age></person>";
return xmlData;
}
};

最後客戶端(使用者)可以這樣使用,

1
2
3
4
5
6
7
8
9
10
11
int main() {
JSONData* jsonData = new JSONData();
XMLData* xmlData = new JSONToXMLAdapter(jsonData);

std::cout << "XML Data: " << xmlData->getXMLData() << std::endl;

delete xmlData;
delete jsonData;

return 0;
}

在這個例子中,JSONToXMLAdapter 類扮演了轉接器的角色。它實現了 XMLData 介面,同時內部持有一個 JSONData 物件。當呼叫 getXMLData() 方法時,轉接器會先取得JSON資料,然後將其轉換為XML格式,從而實現了從JSON到XML的轉換。

轉接器模式的優缺點

轉接器模式的一個顯著優點是,透過使用轉接器我們可以讓原本不相容的系統或類別協同工作,而無需修改它們的原始程式碼。這在處理第三方庫或舊系統時特別有用,因為我們通常無法直接修改這些程式碼。另外轉接器模式還遵循了開放封閉原則,允許我們引入新的轉接器而不會破壞現有的程式碼。

轉接器模式也有缺點。它增加了系統的複雜性,因為引入了新的類和介面。在某些情況下,過度使用轉接器可能會導致程式碼難以理解和維護。由於轉接器模式涉及到不同類別介面之間的轉換,這可能會導致一些性能開銷,特別是在大型應用中,頻繁的介面轉換可能會對系統的效能產生影響,因為它在原介面和目標介面之間增加了一個間接層。

總結

轉接器模式是一種強大的工具,讓我們可以輕鬆地解決系統整合和類別不相容的問題。透過這種模式我們能夠在不改變既有程式碼的前提下,加入新功能或整合外部系統,從而提高系統的靈活性和可擴展性。然而在使用轉接器模式時,也需要考慮到其可能帶來的效能消耗和程式碼複雜性問題。但在許多情況下,轉接器模式帶來的靈活性和複用性遠遠超過了這些小缺點。作為一個優秀的軟體工程師,了解並正確使用轉接器模式可以幫助你更好地處理現實世界中的各種介面不相容問題。