設計模式C++

針對一些經典的常見的場景, 給定了一些對應的解決方案,這個就叫設計模式。

設計模式的作用:使代碼的可重用性高,可讀性強,靈活性好,可維護性強。

設計原則:

單一職責原則:一個類只做一方面的事。

開閉原則:以前寫過的代碼不能動,修改以前寫的代碼是非常危險的事情,我們可以在原來的基礎上進行擴展,例如添加新的方法。

接口隔離原則:接口定義的功能盡量少,不要包含太多的功能。

里氏替換原則:在繼承關系的代碼開發中,如果需要進行功能的擴展,不要在子類中改變父類中已經實現的方法,而是通過新增方法來擴展父類的功能。

依賴倒置原則:在定義類的成員變量,參數類型,返回值類型的時候,不要寫某個具體的實現類,而是盡量采用接口或者抽象類,這樣后續如果我們想改,不需要改動代碼,只需要增加實現類就可以了。

創建型模式:

創建型模式:用于解耦對象實例化的過程。

工廠模式:

工廠模式的思想是將對象的創建邏輯封裝到一個專門的類中,客戶端無需直接?new?具體類,從而降低代碼耦合。

當對象創建邏輯復雜,或需要統一管理創建過程時使用工廠模式。

#include <iostream>// 抽象產品類(接口)
class Shape {
public:virtual void draw() = 0;virtual ~Shape() {} // 虛析構,確保正確釋放子類對象
};// 具體產品類:圓形
class Circle : public Shape {
public:void draw() override {std::cout << "Drawing a Circle" << std::endl;}
};// 具體產品類:方形
class Square : public Shape {
public:void draw() override {std::cout << "Drawing a Square" << std::endl;}
};
簡單工廠模式:

定義抽象產品類,具體產品類,工廠類,用戶不必知道創建對象的細節,只需要調用工廠類(靜態創建對象函數)。(針對單一產品)

違反了開閉原則,新增產品類需要修改工廠類的代碼。

// 工廠類
class ShapeFactory {
public:// 根據類型創建對象(靜態方法)static Shape* createShape(const std::string& type) {if (type == "Circle") {return new Circle();} else if (type == "Square") {return new Square();}return nullptr; // 無效類型返回空}
};// 客戶端代碼
int main() {// 通過工廠創建對象Shape* circle = ShapeFactory::createShape("Circle");Shape* square = ShapeFactory::createShape("Square");circle->draw(); // 輸出: Drawing a Circlesquare->draw(); // 輸出: Drawing a Squaredelete circle;delete square;return 0;
}
工廠方法模式:

創建抽象工廠類,每一個產品對應一個產品工廠。

// 抽象工廠
class ShapeFactory {
public:virtual Shape* createShape() = 0;virtual ~ShapeFactory() {}
};// 圓形工廠
class CircleFactory : public ShapeFactory {
public:Shape* createShape() override {return new Circle();}
};// 方形工廠
class SquareFactory : public ShapeFactory {
public:Shape* createShape() override {return new Square();}
};// 客戶端使用
ShapeFactory* factory = new CircleFactory();
Shape* shape = factory->createShape();
抽象工廠模式:

針對?多個產品族?的創建

#include <iostream>// ----------------- 抽象產品接口 -----------------
// 抽象按鈕
class Button {
public:virtual void render() = 0;virtual ~Button() {}
};// 抽象復選框
class Checkbox {
public:virtual void check() = 0;virtual ~Checkbox() {}
};// ----------------- 具體產品實現 -----------------
// Windows 按鈕
class WindowsButton : public Button {
public:void render() override {std::cout << "Windows 風格按鈕渲染" << std::endl;}
};// Windows 復選框
class WindowsCheckbox : public Checkbox {
public:void check() override {std::cout << "Windows 復選框被勾選" << std::endl;}
};// Mac 按鈕
class MacButton : public Button {
public:void render() override {std::cout << "Mac 風格按鈕渲染" << std::endl;}
};// Mac 復選框
class MacCheckbox : public Checkbox {
public:void check() override {std::cout << "Mac 復選框被勾選" << std::endl;}
};// ----------------- 抽象工廠接口 -----------------
class GUIFactory {
public:virtual Button* createButton() = 0;virtual Checkbox* createCheckbox() = 0;virtual ~GUIFactory() {}
};// ----------------- 具體工廠實現 -----------------
class WindowsFactory : public GUIFactory {
public:Button* createButton() override {return new WindowsButton();}Checkbox* createCheckbox() override {return new WindowsCheckbox();}
};class MacFactory : public GUIFactory {
public:Button* createButton() override {return new MacButton();}Checkbox* createCheckbox() override {return new MacCheckbox();}
};// ----------------- 客戶端代碼 -----------------
int main() {// 假設根據當前系統選擇工廠GUIFactory* factory;// 模擬配置:選擇 Windows 或 Mac 工廠std::string os = "Windows";if (os == "Windows") {factory = new WindowsFactory();} else {factory = new MacFactory();}// 使用工廠創建一組組件Button* button = factory->createButton();Checkbox* checkbox = factory->createCheckbox();button->render();    // 輸出對應系統的按鈕渲染checkbox->check();   // 輸出對應系統的復選框行為delete factory;delete button;delete checkbox;return 0;
}

簡單工廠 vs 工廠方法 vs 抽象工廠?

  • 簡單工廠:一個工廠類負責所有產品。

  • 工廠方法:每個產品對應一個工廠子類。

  • 抽象工廠:生產一個產品家族(例如不同風格的 UI 組件)。

單例模式:

單例設計模式(Singleton Pattern)?是一種創建型設計模式,用于確保一個類只有一個實例,并提供一個全局訪問點來訪問該實例。單例模式無法被回收,他的生命周期隨進程,可以手動釋放或者使用智能指針進行管理。

餓漢模式

餓漢模式:餓漢非常簡單,定義靜態實例,靜態方法在加載到內存時就全部加載出來,缺陷是如果很大啟動時就會花很長時間。

class Singleton {
private:static Singleton instance; // 靜態實例Singleton() {} // 私有構造函數// 禁止拷貝構造函數和賦值操作符,防止拷貝Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:static Singleton* getInstance() {return &instance; // 直接返回靜態實例的地址}
};// 在類外部初始化靜態實例
Singleton Singleton::instance;
懶漢模式

懶漢模式:懶漢的核心思想是“延遲加載”,使用時再創建實例,使用雙重檢查鎖確保線程安全和同步開銷。

#include <mutex>class Singleton {
private:static Singleton* instance; // 靜態實例指針static std::mutex mutex; // 互斥鎖,用于線程同步Singleton() {} // 私有構造函數// 禁止拷貝構造函數和賦值操作符,防止拷貝Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;public:static Singleton* getInstance() {if (instance == nullptr) { // 雙重檢查鎖定(Double-Checked Locking)std::lock_guard<std::mutex> lock(mutex); // 加鎖if (instance == nullptr) { // 再次檢查實例是否已創建instance = new Singleton(); // 如果未創建,則創建實例}}return instance; // 返回實例的地址}
};// 在類外部初始化靜態實例指針和互斥鎖
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;
Meyer's Singleton

使用靜態局部變量實現的單例模式。靜態局部變量的初始化是線程安全的。編譯器會確保靜態局部變量只被初始化一次,即使多個線程同時調用?getInstance()。同時避免了資源浪費。實現簡單,是現代 C++ 中推薦的單例實現方式。

class Singleton {
private:Singleton() {} // 私有構造函數Singleton(const Singleton&) = delete; // 禁止拷貝構造Singleton& operator=(const Singleton&) = delete; // 禁止賦值操作public:static Singleton& getInstance() {static Singleton instance; // 靜態局部變量return instance;}void doSomething() {std::cout << "Singleton is doing something!" << std::endl;}
};
應用場景:?

線程池,內存池

結構型模式:

結構型模式:把類和對象結合在一起形成一個更大的結構。

行為型模式:

行為性模式:類和對象如何交互,劃分責任和算法。

策略模式:

允許使用者根據不同的情況選擇不同的策略(算法或行為)執行。

  1. 抽象策略接口(SortStrategy
    定義所有具體策略必須實現的方法(如?sort())。

  2. 具體策略類(BubbleSortQuickSort
    實現具體的算法邏輯。

  3. 上下文類(Sorter

    • 持有策略對象的引用(通過組合關系)。

    • 提供設置策略的方法(setStrategy())和執行策略的方法(executeSort())。

#include <iostream>
#include <vector>
#include <memory>// ----------------- 1. 抽象策略接口 -----------------
class SortStrategy {
public:virtual void sort(std::vector<int>& data) = 0;virtual ~SortStrategy() {} // 虛析構確保正確釋放資源
};// ----------------- 2. 具體策略類 -----------------
// 冒泡排序策略
class BubbleSort : public SortStrategy {
public:void sort(std::vector<int>& data) override {std::cout << "使用冒泡排序" << std::endl;// 實現冒泡排序邏輯...}
};// 快速排序策略
class QuickSort : public SortStrategy {
public:void sort(std::vector<int>& data) override {std::cout << "使用快速排序" << std::endl;// 實現快速排序邏輯...}
};// ----------------- 3. 上下文類(Context) -----------------
class Sorter {
private:std::unique_ptr<SortStrategy> strategy; // 使用智能指針管理策略對象public:// 設置策略void setStrategy(std::unique_ptr<SortStrategy> newStrategy) {strategy = std::move(newStrategy);}// 執行排序void executeSort(std::vector<int>& data) {if (strategy) {strategy->sort(data);} else {std::cout << "未設置排序策略!" << std::endl;}}
};// ----------------- 客戶端代碼 -----------------
int main() {Sorter sorter;std::vector<int> data = {5, 2, 7, 1, 3};// 動態切換策略sorter.setStrategy(std::make_unique<BubbleSort>());sorter.executeSort(data); // 輸出:使用冒泡排序sorter.setStrategy(std::make_unique<QuickSort>());sorter.executeSort(data); // 輸出:使用快速排序return 0;
}
應用場景:

游戲中的角色行為:角色根據狀態切換攻擊、防御、逃跑策略。

動態使用不同的算法。

觀察者模式:

定義對象間的一對多依賴關系,當一個對象(主題)狀態改變時,所有依賴它的對象(觀察者)會自動收到通知并更新。

應用場景:訂閱-通知機制,實現松耦合的一對多事件處理。比如氣象觀測,觀測機器觀察到了數據,通知各類的軟件。

中介者模式:

用一個中介對象(Mediator)來封裝一組對象(Colleague)之間的交互,從而減少對象間的直接耦合。所有對象通過中介者通信,而不是直接相互引用。

應用場景:聊天室

模版模式:

在父類中定義一個規定了算法的執行步驟和順序的模板方法,聲明為?final,再將算法中的步驟聲明為抽象方法或虛函數,由子類具體實現。

#include <iostream>// 抽象基類:定義飲料制作的模板
class Beverage {
public:// 模板方法(final 禁止子類修改流程)void prepareBeverage() final {boilWater();brew();addCondiments();pourInCup();}protected:// 具體步驟由子類實現virtual void brew() = 0;virtual void addCondiments() = 0;// 公共步驟(直接復用)void boilWater() {std::cout << "煮沸水" << std::endl;}void pourInCup() {std::cout << "倒入杯子" << std::endl;}virtual ~Beverage() = default;
};// 具體子類:咖啡
class Coffee : public Beverage {
protected:void brew() override {std::cout << "沖泡咖啡粉" << std::endl;}void addCondiments() override {std::cout << "加糖和牛奶" << std::endl;}
};// 具體子類:茶
class Tea : public Beverage {
protected:void brew() override {std::cout << "浸泡茶葉" << std::endl;}void addCondiments() override {std::cout << "加檸檬" << std::endl;}
};// 客戶端代碼
int main() {Beverage* coffee = new Coffee();coffee->prepareBeverage();// 輸出:// 煮沸水// 沖泡咖啡粉// 加糖和牛奶// 倒入杯子Beverage* tea = new Tea();tea->prepareBeverage();// 輸出:// 煮沸水// 浸泡茶葉// 加檸檬// 倒入杯子delete coffee;delete tea;return 0;
}
應用場景:

比如餐廳服務員的游戲,制作可樂,雪碧什么的飲料都是一樣的步驟,就可以設定一個制作飲料的類,里面規定制作飲料的步驟。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73265.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73265.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73265.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32上實現簡化版的AUTOSAR DEM模塊

文章目錄 摘要摘要 在一些可以不使用AUTOSAR的項目中,往往也有故障檢測和DTC存儲的需求,開發一套類似于AUTOSAR DEM模塊的軟件代碼,能夠滿足DTC的檢出和存儲,使用FalshDB代替Nvm模塊,輕松構建持久化存儲,如果你也有這樣的需求,請閱讀本篇,希望能夠幫到你。 /*********…

html css網頁制作成品——糖果屋網頁設計(4頁)附源碼

目錄 一、&#x1f468;?&#x1f393;網站題目 二、??網站描述 三、&#x1f4da;網站介紹 四、&#x1f310;網站效果 五、&#x1fa93; 代碼實現 &#x1f9f1;HTML 六、&#x1f947; 如何讓學習不再盲目 七、&#x1f381;更多干貨 一、&#x1f468;?&#x1f…

Postman下載安裝及簡單入門

一&#xff0e;Postman簡介 Postman是一款API測試工具&#xff0c;可以幫助開發、測試人員發送HTTP請求&#xff0c;與各種API進行交互&#xff0c;并分析響應 二&#xff0e;下載與安裝 訪問Postman官網&#xff08;https://www.postman.com/&#xff09;&#xff0c;下載適…

免費blender模型網站推薦

前言:博主最近在玩blender建模,有時為了節省時間想用現成的模型,網上零零碎碎的大多多需要付費,自己找了些好用且免費的blender素材庫網站,希望對你有幫助 綜合資源網站 Blender布的 網址:https://blenderco.cn/ 簡介:提供上萬個Blender模型、插件、貼圖資源,更新頻率高…

基于C語言的簡單HTTP Web服務器實現

1. 概述 本案例使用C語言實現了一個簡單的HTTP服務器&#xff0c;能夠處理客戶端的GET請求&#xff0c;并返回靜態文件&#xff08;如HTML、圖片等&#xff09;。在此案例中案例&#xff0c;我們主要使用的知識點有&#xff1a; Socket編程&#xff1a;基于TCP協議的Socket通信…

大型語言模型與強化學習的融合:邁向通用人工智能的新范式

1. 引言 大型語言模型&#xff08;LLM&#xff09;在自然語言處理領域的突破&#xff0c;展現了強大的知識存儲、推理和生成能力&#xff0c;為人工智能帶來了新的可能性。強化學習&#xff08;RL&#xff09;作為一種通過與環境交互學習最優策略的方法&#xff0c;在智能體訓…

langchain--LCEL

文章目錄 介紹優勢運行接口 介紹 LCEL的全稱是Lang Chain Expression Language。其實他的用處就是使用“|”運算符鏈接LangChain應用的各個組件。 是一種聲明式的方法來鏈接Langchain組件。LCEL從第一天起就被設計為支持將原型投入生產&#xff0c;無需代碼更改&#xff0c;從…

PyQt基礎——簡單的窗口化界面搭建以及槽函數跳轉

一、代碼實現 import sysfrom PyQt6.QtGui import QPixmap from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QLineEdit, QMessageBox from PyQt6.uic import loadUi from PyQt6.QtCore import Qtclass LoginWindow(QWidget):def __init__(self):sup…

Android 11.0 監聽某個app啟動或者退出功能實現

1.前言 在進行11.0的系統定制開發中,在某些app的定制過程中,需要知道某個app的啟動記錄和退出記錄, 所以就需要監聽某個app的啟動和退出的過程,需要在Activity的生命周期中來實現監聽功能 2.監聽某個app啟動或者退出功能實現的核心類 frameworks\base\core\java\android…

再談 Multiscale deformable attention

文章目錄 DCN 可變形卷積單尺度 deformable attention多尺度&#xff08;multiscale&#xff09; deformable attention精華代碼&#xff1a;deformbale attentionattention 計算&#xff1a;獲取不同尺度參考點&#xff1a; DCN 可變形卷積 deformable attention 靈感來源可變…

Java 大視界 -- Java 大數據在智慧文旅虛擬導游與個性化推薦中的應用(130)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

多源 BFS_多源最短路(十八)542. 01 矩陣 中等 超級源點思想

542. 01 矩陣 給定一個由 0 和 1 組成的矩陣 mat &#xff0c;請輸出一個大小相同的矩陣&#xff0c;其中每一個格子是 mat 中對應位置元素到最近的 0 的距離。 兩個相鄰元素間的距離為 1 。 示例 1&#xff1a; 輸入&#xff1a;mat [[0,0,0],[0,1,0],[0,0,0]] 輸出&#xff…

Ubuntu24.04 LTS 版本 Linux 系統在線和離線安裝 Docker 和 Docker compose

一、更換軟件源并更新系統 在 Ubuntu 24.04 LTS 中&#xff0c;系統引入了全新的軟件源配置格式。現在的源配置文件內容更加結構化且清晰&#xff0c;主要包含了軟件類型 (Types)、源地址 (URIs)、版本代號 (Suites) 以及組件 (Components) 等信息。 # cat /etc/apt/sources.li…

c++介紹智能指針 十二(2)

智能指針share_ptr,與unique_ptr不同&#xff0c;多個shar_ptr對象可以共同管理一個指針&#xff0c;它們通過一個共同的引用計數器來管理指針。當一個智能指針對象銷毀時&#xff0c;計數器減一。當計數器為0時&#xff0c;會將所指向的內存對象釋放。 #include<memory>…

react和vue 基礎使用對比

1.實現功能&#xff08;ts&#xff09; 0.基礎屬性使用 1.組件直接的通信 2.useState 動態修改值 3.循環遍歷功能 4.實現類型vue 的 watch &#xff0c;filter&#xff0c;computed 屬性功能 5.實現類似vue2的生命周期 5.類型vue v-if功能的實現 2.文件結構圖 3.具體代碼 in…

深度學習 常見優化器

一、基礎優化器 隨機梯度下降&#xff08;SGD&#xff09; ? 核心&#xff1a;?θJ(θ) η * ?θJ(θ) ? 特點&#xff1a;學習率固定&#xff0c;收斂路徑震蕩大 ? 適用場景&#xff1a;簡單凸優化問題 ? 改進方向&#xff1a;動量加速 二、動量系優化器 2. SGD with…

監控快手關注列表更新以及去視頻水印視頻

def printData(self):if len(self.UpdateDataList) > 0:self.UpdateDataList sorted(self.UpdateDataList, keylambda x: x[minutes]) # 先更新的在前sucess 0for index, video in enumerate(self.UpdateDataList):minutes video[minutes]if minutes > self.updateIn…

前端 JavaScript 中快速發起多個下載請求時,解決瀏覽器的并發下載連接限制

為什么會漏掉鏈接&#xff1f; 當你在前端 JavaScript 中快速發起多個下載請求時&#xff0c;瀏覽器可能無法同時處理所有請求&#xff0c;導致一些請求被忽略。這通常與瀏覽器的并發連接限制有關&#xff0c;例如 Chrome 可能限制每秒下載 10 個文件。 如何避免漏掉鏈接&…

如何修改桌面圖標——文件夾圖標(Windows 10)

修改文件夾圖標 EX&#xff1a;新建文件夾&#xff0c;程序創建文件夾等 修改桌面文件夾圖標&#xff0c;打開右鍵菜單功能項&#xff0c;點擊“屬性” 在屬性窗口頁面找到并單擊自定義&#xff0c;然后點擊“更改圖標” 從列表中選擇喜歡的圖標&#xff0c;或點擊瀏覽選擇個…

LiveCommunicationKit OC 實現

一、實現效果: ? LiveCommunicationKit?是蘋果公司在iOS 17.4、watchOS 10.4和visionOS 1.1中引入的一個新框架,旨在優化VoIP通話的交互體驗。該框架提供了與