在C++編碼中,"方便擴展"通常指的是代碼設計具有良好的**可維護性、可重用性和靈活性**,能夠在不修改原有代碼或僅少量修改的情況下,輕松添加新功能、支持新類型或適應新需求。以下是一些典型的、體現“方便擴展”思想的C++編程案例:
?
---
?
### 1. **模板 (Templates) - 支持任意類型**
?
這是C++實現泛型編程的核心,讓代碼可以處理多種數據類型而無需重寫。
?
**案例:實現一個通用的最大值函數**
```cpp
template <typename T>
T max(T a, T b) {
? ? return (a > b) ? a : b;
}
?
// 使用
int i = max(3, 5); // int
double d = max(3.14, 2.71); // double
std::string s = max("hello", "world"); // string
```
?
**擴展性體現:**
- 無需為 `int`、`double`、`std::string` 等每種類型寫一個 `max` 函數。
- 新增自定義類型(如 `Point`)時,只要重載 `>` 操作符,即可直接使用。
?
---
?
### 2. **繼承與多態 (Inheritance & Polymorphism) - 支持新類**
?
通過基類指針操作派生類對象,新增功能只需添加新類,無需修改使用代碼。
?
**案例:圖形繪制系統**
```cpp
class Shape {
public:
? ? virtual void draw() = 0;
? ? virtual ~Shape() = default;
};
?
class Circle : public Shape {
public:
? ? void draw() override { cout << "Drawing Circle\n"; }
};
?
class Rectangle : public Shape {
public:
? ? void draw() override { cout << "Drawing Rectangle\n"; }
};
?
// 擴展:新增 Triangle 類
class Triangle : public Shape {
public:
? ? void draw() override { cout << "Drawing Triangle\n"; }
};
?
// 使用代碼(無需修改)
void renderShapes(const vector<Shape*>& shapes) {
? ? for (auto shape : shapes) {
? ? ? ? shape->draw(); // 自動調用對應 draw()
? ? }
}
```
?
**擴展性體現:**
- 添加新圖形(如 `Triangle`)時,只需新增類,`renderShapes` 函數完全不用改。
?
---
?
### 3. **策略模式 (Strategy Pattern) - 支持新算法**
?
將算法封裝成獨立的類,可以在運行時切換。
?
**案例:排序策略**
```cpp
class SortStrategy {
public:
? ? virtual void sort(vector<int>& data) = 0;
? ? virtual ~SortStrategy() = default;
};
?
class QuickSort : public SortStrategy {
public:
? ? void sort(vector<int>& data) override { /* 快速排序實現 */ }
};
?
class MergeSort : public SortStrategy {
public:
? ? void sort(vector<int>& data) override { /* 歸并排序實現 */ }
};
?
class Context {
? ? SortStrategy* strategy;
public:
? ? void setStrategy(SortStrategy* s) { strategy = s; }
? ? void executeSort(vector<int>& data) { strategy->sort(data); }
};
```
?
**擴展性體現:**
- 要添加 `HeapSort`,只需新增類并繼承 `SortStrategy`,Context 無需修改。
?
---
?
### 4. **工廠模式 (Factory Pattern) - 支持新對象創建**
?
將對象的創建過程封裝起來,新增類型時只需注冊,不改核心邏輯。
?
**案例:GUI控件工廠**
```cpp
class Widget {
public:
? ? virtual void render() = 0;
? ? virtual ~Widget() = default;
};
?
class Button : public Widget { /* ... */ };
class Label : public Widget { /* ... */ };
?
class WidgetFactory {
? ? map<string, function<Widget*()>> creators;
public:
? ? void registerType(const string& name, function<Widget*()> creator) {
? ? ? ? creators[name] = creator;
? ? }
?
? ? Widget* create(const string& type) {
? ? ? ? return creators[type]();
? ? }
};
?
// 使用
WidgetFactory factory;
factory.registerType("button", [](){ return new Button; });
factory.registerType("label", [](){ return new Label; });
?
Widget* btn = factory.create("button"); // 創建按鈕
```
?
**擴展性體現:**
- 添加新控件(如 `TextBox`),只需注冊,`create` 接口不變。
?
---
?
### 5. **觀察者模式 (Observer Pattern) - 支持新事件響應**
?
一個對象狀態改變時,通知所有依賴對象。新增響應者無需修改主體。
?
**案例:事件系統**
```cpp
class EventManager {
? ? vector<function<void()>> listeners;
public:
? ? void subscribe(function<void()> callback) {
? ? ? ? listeners.push_back(callback);
? ? }
?
? ? void notify() {
? ? ? ? for (auto& f : listeners) f();
? ? }
};
?
// 多個模塊可以監聽
EventManager em;
em.subscribe([](){ cout << "Log: Event occurred\n"; });
em.subscribe([](){ saveToFile(); });
em.subscribe([](){ updateUI(); });
?
em.notify(); // 觸發所有回調
```
?
**擴展性體現:**
- 新增監聽邏輯(如發送郵件、寫日志)只需調用 `subscribe`,`notify` 不變。
?
---
?
### 6. **插件式架構 (Plugin Architecture) - 支持動態加載**
?
使用動態庫(`.dll` / `.so`)和接口,運行時加載新功能。
?
**案例:圖像格式支持**
- 主程序定義 `ImageDecoder` 接口。
- 每種格式(PNG、JPEG、WebP)實現為獨立 `.dll`。
- 程序啟動時掃描插件目錄,自動加載并注冊。
?
**擴展性體現:**
- 添加 WebP 支持?只需提供一個 `.dll`,無需重新編譯主程序。
?
---
?
### 總結:如何讓C++代碼“方便擴展”
?
| 技術 | 適用擴展場景 | 關鍵思想 |
|------|--------------|----------|
| **模板** | 新數據類型 | 編譯時泛型 |
| **繼承/多態** | 新子類行為 | 運行時多態 |
| **策略模式** | 新算法 | 封裝變化的算法 |
| **工廠模式** | 新對象創建 | 解耦創建與使用 |
| **觀察者模式** | 新事件響應 | 發布-訂閱機制 |
| **插件架構** | 新功能模塊 | 動態加載 |
?
**核心原則**:**開閉原則 (Open/Closed Principle)** —— 對擴展開放,對修改關閉。