????????橋接模式(Bridge Pattern)和組合模式(Composite Pattern)都是結構型設計模式,旨在解決對象結構的復雜性問題,但它們的應用場景和目的有所不同。以下是它們的區別:
1. 定義與目的
橋接模式(Bridge Pattern):
- 定義:將抽象部分與它的實現部分分離,使它們可以獨立地變化。
- 目的:主要解決在多維度變化情況下,類的爆炸性增長問題。通過將兩個或多個維度的變化分離到不同的類層次中,從而使得系統更具靈活性。
組合模式(Composite Pattern):
- 定義:將對象組合成樹形結構以表示“部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
- 目的:主要解決對象的層次結構問題,使得客戶端可以一致地處理單個對象和組合對象。
2. 主要使用場景
橋接模式:
- 當一個類有多個變化維度,并且這些維度需要獨立變化時使用橋接模式。例如,一個圖形類可能有形狀和顏色兩個變化維度,那么可以將形狀和顏色分離為兩個獨立的層次結構。
- 當不希望在抽象和實現之間產生緊耦合時。
組合模式:
- 當需要表示對象的部分-整體層次結構時使用組合模式。
- 當希望客戶端可以統一地處理單個對象和組合對象時。
3. 結構區別
????????橋接模式:包含兩個獨立的層次結構,一個是抽象部分,一個是實現部分。抽象部分包含對實現部分的引用。
????????組合模式:包含一個對象樹的層次結構,葉子節點表示基本對象,組合節點表示容器對象。容器對象可以包含葉子節點或其他容器節點。
4. 示例代碼對比
橋接模式(Bridge Pattern)
????????目的:將抽象部分與它的實現部分分離,使它們可以獨立地變化。
類比
????????想象一下,你在設計一種繪圖應用程序,這個應用程序可以繪制不同種類的形狀(例如,圓形和方形),而每種形狀可以用不同的顏色來繪制(例如,紅色和藍色)。在這種情況下,形狀與顏色是兩個獨立的維度。
如果不用橋接模式,你可能會為每種情況創建一個類:
- 紅色的圓形
- 藍色的圓形
- 紅色的方形
- 藍色的方形
????????這樣類的數量會隨著形狀和顏色的增加而成倍增長(組合爆炸)。
橋接模式的解決方案:
????????將形狀和顏色分開處理。你創建一個形狀的抽象類,并且它包含一個顏色的接口。然后你可以獨立地擴展形狀和顏色。
// 顏色接口
class Color {
public:virtual std::string fill() const = 0;virtual ~Color() = default;
};class Red : public Color {
public:std::string fill() const override {return "紅色";}
};class Blue : public Color {
public:std::string fill() const override {return "藍色";}
};// 形狀抽象類
class Shape {
protected:std::shared_ptr<Color> color;
public:Shape(std::shared_ptr<Color> col) : color(col) {}virtual std::string draw() const = 0;virtual ~Shape() = default;
};class Circle : public Shape {
public:Circle(std::shared_ptr<Color> col) : Shape(col) {}std::string draw() const override {return "繪制一個" + color->fill() + "的圓形";}
};class Square : public Shape {
public:Square(std::shared_ptr<Color> col) : Shape(col) {}std::string draw() const override {return "繪制一個" + color->fill() + "的方形";}
};// 使用
int main() {std::shared_ptr<Color> red = std::make_shared<Red>();std::shared_ptr<Color> blue = std::make_shared<Blue>();std::shared_ptr<Shape> redCircle = std::make_shared<Circle>(red);std::shared_ptr<Shape> blueSquare = std::make_shared<Square>(blue);std::cout << redCircle->draw() << std::endl; // 輸出: 繪制一個紅色的圓形std::cout << blueSquare->draw() << std::endl; // 輸出: 繪制一個藍色的方形return 0;
}
組合模式(Composite Pattern)
????????目的:將對象組合成樹形結構以表示“部分-整體”的層次結構,使得用戶對單個對象和組合對象的使用具有一致性。
類比
????????想象一下,你在設計一個公司組織架構,這個組織架構中有部門和員工。部門可以包含子部門和員工,子部門又可以包含員工或更多的子部門,形成一個樹形結構。
組合模式的解決方案:
????????你創建一個通用的組件接口,它可以表示部門和員工,然后通過組合對象來表示部門,通過葉子對象來表示員工。
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>// 組件接口
class Employee {
public:virtual void showDetails() const = 0;virtual void add(std::shared_ptr<Employee> employee) {}virtual void remove(std::shared_ptr<Employee> employee) {}virtual ~Employee() = default;
};// 葉子節點
class Developer : public Employee {
private:std::string name;
public:Developer(const std::string& devName) : name(devName) {}void showDetails() const override {std::cout << "開發者: " << name << std::endl;}
};// 葉子節點
class Designer : public Employee {
private:std::string name;
public:Designer(const std::string& desName) : name(desName) {}void showDetails() const override {std::cout << "設計師: " << name << std::endl;}
};// 容器節點
class Manager : public Employee {
private:std::string name;std::vector<std::shared_ptr<Employee>> subordinates;
public:Manager(const std::string& mgrName) : name(mgrName) {}void showDetails() const override {std::cout << "經理: " << name << std::endl;for (const auto& subordinate : subordinates) {subordinate->showDetails();}}void add(std::shared_ptr<Employee> employee) override {subordinates.push_back(employee);}void remove(std::shared_ptr<Employee> employee) override {subordinates.erase(std::remove(subordinates.begin(), subordinates.end(), employee), subordinates.end());}
};// 使用
int main() {std::shared_ptr<Employee> dev1 = std::make_shared<Developer>("Alice");std::shared_ptr<Employee> dev2 = std::make_shared<Developer>("Bob");std::shared_ptr<Employee> des1 = std::make_shared<Designer>("Charlie");std::shared_ptr<Manager> mgr1 = std::make_shared<Manager>("Dave");mgr1->add(dev1);mgr1->add(dev2);mgr1->add(des1);std::shared_ptr<Employee> des2 = std::make_shared<Designer>("Eve");std::shared_ptr<Manager> generalManager = std::make_shared<Manager>("Frank");generalManager->add(mgr1);generalManager->add(des2);generalManager->showDetails();// 輸出:// 經理: Frank// 經理: Dave// 開發者: Alice// 開發者: Bob// 設計師: Charlie// 設計師: Evereturn 0;
}
總結
- 橋接模式:
- 用于分離抽象和實現,使它們可以獨立變化。
- 適用于多維度變化的場景,如形狀和顏色的組合。
- 組合模式:
- 用于構建對象的樹形結構,使得單個對象和組合對象可以一致地處理。
- 適用于表示部分-整體層次結構的場景,如公司組織架構。