C++設計模式---面向對象原則

面向對象設計原則

原則的目的:高內聚,低耦合

1. 單一職責原則

類的職責單一,對外只提供一種功能,而引起類變化的原因都應該只有一個。

2. 開閉原則

對擴展開放,對修改關閉;增加功能是通過增加代碼來實現的,而不是去修改源代碼。

#include<iostream>
using namespace std;//開閉原則
//對擴展開放,對修改關閉;增加功能是通過增加代碼來實現的,而不是去修改源代碼//寫一個抽象類
class AbstractCaculator
{
public:virtual int getResult() = 0;virtual void setOperatorNumber(int a, int b) = 0;
};//加法計算類
class AddCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA + mB;}public:int mA;int mB;
};//減法計算器
class SubCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA - mB;}public:int mA;int mB;
};//乘法計算器
class MolCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA * mB;}public:int mA;int mB;
};//取模計算器	通過增加代碼來實現
class MulCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA % mB;}public:int mA;int mB;
};void test01()
{AbstractCaculator* caculator = new AddCaculator;caculator->setOperatorNumber(10, 20);cout << "ret:" << caculator->getResult() << endl;delete caculator;caculator = new SubCaculator;caculator->setOperatorNumber(10, 20);cout << "ret:" << caculator->getResult() << endl;
}int main()
{test01();return 0;
}

3. 里氏代換原則

任何抽象類出現的地方都可以用他的實現類進行替換,實際就是虛擬機制,語言級別實現面向對象功能。?

4. 依賴倒轉原則

依賴于抽象(接口),不要依賴具體的實現(類),也就是針對接口編程。?

傳統方式:

#include<iostream>
using namespace std;//銀行工作人員
class BankWorker
{public:void saveService(){cout << "辦理存款業務..." << endl;}void payService(){cout << "辦理支付業務..." << endl;}void tranferService(){cout << "辦理轉賬業務..." << endl;}
};//中層模塊
void doSaveBussiness(BankWorker* worker) {worker->saveService();
}void doPayBussiness(BankWorker* worker) {worker->payService();
}void doTranferBussiness(BankWorker* worker) {worker->tranferService();
}void test04() {BankWorker* worker = new BankWorker;doSaveBussiness(worker);  //辦理存款業務doPayBussiness(worker); //辦理支付業務doTranferBussiness(worker); //辦理轉賬業務
}int main()
{test04();return 0;
}

依賴倒轉原則:?

#include<iostream>
using namespace std;//銀行工作人員
class AbstractWorker
{
public:virtual void doBusiness() = 0;
};//專門辦理存款業務的工作人員
class SaveBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "辦理存款業務..." << endl;}
};//專門辦理支付業務的工作人員
class PayBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "辦理支付業務..." << endl;}
};//專門辦理轉賬業務的工作人員
class TransferBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "辦理轉賬業務..." << endl;}
};//中層業務
void doNewBussiness(AbstractWorker* worker)
{worker->doBusiness();
}void test04_1()
{AbstractWorker* transfer = new TransferBankWorker;doNewBussiness(transfer);
}int main()
{test04_1();return 0;
}

5. 接口隔離原則

????????不應該強迫用戶的程序依賴他們不需要的接口方法。一個接口應該只提供一種對外功能,不應該把所有操作都封裝到一個接口中去。?

6. 迪米特法則(最少知識原則)?

????????一個對象應當對其他對象盡可能少的了解,從而降低各個對象之間的耦合,提高系統的可維護性。例如在一個程序中,各個模塊之間相互調用時,通常會提供一個統一的接口來實現。這樣其他模塊不需要了解另外一個模塊的內部實現細節,這樣當一個模塊內部的實現發生改變時,不會影響其他模塊的使用。(黑盒原理)

#include<iostream>
#include<string>
#include<vector>
using namespace std;//迪米特法則---最少知識原則
class AbstractBuilding
{
public:virtual void sale() = 0;virtual string getQuality() = 0;
};//樓盤A
class BuildingA : public AbstractBuilding
{
public:BuildingA(){m_Quality = "高品質";}virtual void sale(){cout << "樓盤A" << m_Quality << "被售賣!" << endl;}virtual string getQuality(){return m_Quality;}public:string m_Quality;
};//樓盤B
class BuildingB : public AbstractBuilding
{
public:BuildingB(){m_Quality = "低品質";}virtual void sale(){cout << "樓盤B" << m_Quality << "被售賣!" << endl;}virtual string getQuality(){return m_Quality;}
public:string m_Quality;
};//客戶端
void test02()
{BuildingA* ba = new BuildingA;if (ba->m_Quality == "高品質"){ba->sale();}BuildingB* bb = new BuildingB;if (bb->m_Quality == "低品質"){bb->sale();}
}//中介類
class Mediator
{
public:Mediator(){AbstractBuilding* building = new BuildingA;vBuilding.push_back(building);building = new BuildingB;vBuilding.push_back(building);}//對外提供接口AbstractBuilding* findMyBuilding(string quality){for (vector<AbstractBuilding*>::iterator it = vBuilding.begin(); it != vBuilding.end(); it++)if ((*it)->getQuality() == quality){return *it;}return NULL;}~Mediator(){for (vector<AbstractBuilding *>::iterator it = vBuilding.begin();it != vBuilding.end();it++)if (*it != NULL){delete* it;}}public:vector<AbstractBuilding *> vBuilding;
};void test02_1()
{Mediator* meidator = new Mediator;AbstractBuilding* building = meidator->findMyBuilding("高品質");if (building != NULL){building->sale();}else{cout << "沒有符合條件的樓盤!" << endl;}
}int main()
{test02();test02_1();return 0;
}

7. 合成復用原則

如果使用繼承,會導致父類的任何變換都可能影響到子類的行為。

如果使用對象組合,就降低了這種依賴關系。
對于繼承和組合,優先使用組合。

#include<iostream>
using namespace std;//抽象車
class AbstructCar
{
public:virtual void run() = 0;
};//大眾車
class Dazhong :public AbstructCar
{
public:virtual void run(){cout << "大眾車啟動" << endl;}
};//拖拉機
class Tuolaji :public AbstructCar
{
public:virtual void run(){cout << "拖拉機啟動" << endl;}
};//針對具體類,不適用繼承
#if 0
class Person :public Tuolaji
{
public:void Douofeng(){run();}
};class PersonB :public Dazhong
{
public:void Douofeng(){run();}
};
#endif//可以使用組合
class Person
{
public:void setCar(AbstructCar *car){this->car = car;}void Doufeng(){this->car->run();if (this->car != NULL){delete this->car;this->car = NULL;}}public:AbstructCar* car;
};void test03()
{Person* p = new Person;p->setCar(new Dazhong);p->Doufeng();p->setCar(new Tuolaji);p->Doufeng();delete p;
}//繼承和組合 優先使用組合
int main()
{test03();return 0;
}

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

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

相關文章

【linux特殊符號】

文章目錄 學習目標一、Linux的特殊符號1.系統變量2.引號 總結 學習目標 1.學會查看系統變量 2.學會各種引號 3.一、Linux的特殊符號 1.系統變量 windows系統變量&#xff1a;echo %path% linux系統變量&#xff1a;echo $PATH2.引號 " " 雙引號&#xff0c;換行…

如何基于springboot構建cas最新版源碼?

環境準備 下載JDK21 https://download.oracle.com/java/21/archive/jdk-21.0.2_windows-x64_bin.zip下載gradle 8.5并配置環境變量 https://gradle.org/next-steps/?version8.5&formatbin下載項目git clone http://gitlab.ruishan.cc/meta/anka-authentication.git 開始…

Maven工具

Maven是apache軟件基金會的一個開源項目 是一個項目構建&#xff08;項目管理&#xff09;工具 用來幫助開發者管理項目中的 jar文件,以及 jar文件 之間的依賴關系(在A.jar文件中&#xff0c;用到了B.jar)、完成項目的編譯&#xff08;.java->.class&#xff09;、測試、打…

web前端項目已有阿里巴巴圖標基礎上,再次導入阿里巴巴圖標的方法

如果是第一次導入阿里巴巴圖標請參考: vue項目引入阿里云圖標_vue引用阿里云圖標fontclass-CSDN博客 本文主要想講在項目原有阿里巴巴圖標基礎上,再次導入阿里巴巴圖標的解決辦法: 1.iconfont.json對應修改就行,這個簡單一看就明白; 2.iconfont.js主要改動<symbol><…

從零入門激光SLAM(二十)——IESKF代碼實現

大家好呀&#xff0c;我是一個SLAM方向的在讀博士&#xff0c;深知SLAM學習過程一路走來的坎坷&#xff0c;也十分感謝各位大佬的優質文章和源碼。隨著知識的越來越多&#xff0c;越來越細&#xff0c;我準備整理一個自己的激光SLAM學習筆記專欄&#xff0c;從0帶大家快速上手激…

Ansible自動化運維中的file文件模塊模塊應用詳解

作者主頁&#xff1a;點擊&#xff01; Ansible專欄&#xff1a;點擊&#xff01; 創作時間&#xff1a;2024年5月21日15點21分 &#x1f4af;趣站推薦&#x1f4af; 前些天發現了一個巨牛的&#x1f916;人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xf…

【Java筆記】第8章:面向對象的三大特性(封裝、繼承、多態)

前言1. 三大特性概述2. 封裝3. 繼承4. 多態結語 #include<GUIQU.h> int main { 上期回顧:【Java筆記】第7章&#xff1a;面向對象 個人主頁&#xff1a;C_GUIQU 歸屬專欄&#xff1a;【Java學習】 return 一鍵三連; } 前言 各位小伙伴大家好&#xff01;上期小編給大家…

后端技術常用網站

技術說明官網SpringBootMVC框架https://spring.io/projects/spring-bootSpringCloud微服務框架https://spring.io/projects/spring-cloud/MyBatis-PlusORM框架https://mp.baomidou.com/Swagger-UI文檔生產工具https://github.com/swagger-api/swagger-uiKibana分析和可視化平臺…

SO_REUSEPORT 之 TCP負載均衡驗證

首先啟動兩個tcp server&#xff0c; 代碼里開啟 SO_REUSEPORT [my_testlocalhost test]$ ./tcp_server_reuseport & [1] 1864 [my_testlocalhost test]$ Server listening on port 8888[my_testlocalhost test]$ ./tcp_server_reuseport & [2] 1865 [my_testlocalh…

網絡工程師備考1——基礎學習

認識設備 1 交換機 一、什么是交換機&#xff1f; 實現不同電腦之間數據的轉發 換機是一種用于電(光)信號轉發的網絡設備。 它可以為接入交換機的任意兩個網絡節點提供獨享的電信號通路。最常見的交換機是以太網交換機。交換機工作于OSI參考模型的第二層&#xff0c;即數據…

使用 Supabase 的 Realtime + Storage 非常方便呢

文章目錄 &#xff08;一&#xff09;Supabase&#xff08;二&#xff09;Realtime&#xff08;消息&#xff09;&#xff08;2.1&#xff09;Python 消息訂閱&#xff08;2.2&#xff09;JavaScript 消息訂閱 &#xff08;三&#xff09;Storage&#xff08;存儲&#xff09;&…

Linux:Ubuntu修改root密碼

Linux&#xff1a;Ubuntu修改root密碼 修改默認grub配置文件 rootshanxin:~# vim /etc/default/grub# 主要修改內容如下&#xff1a;GRUB_DEFAULT0 #GRUB_TIMEOUT_STYLEhidden 注釋這一行 GRUB_TIMEOUT5 # 將這一行的時間改為5秒進行開啟啟動的grub文件的復寫 rootshanxin:~…

芯課堂 | UI Creator 物理鍵盤移植指南

LVGL提供輸入設備的種類一共有5種&#xff0c;分別是&#xff1a;touchpad&#xff08;觸摸板&#xff09;、mouse&#xff08;鼠標&#xff09;、keypad&#xff08;鍵盤&#xff09;、encoder&#xff08;編碼器&#xff09;、button&#xff08;外部按鍵&#xff09;。而基于…

Tron 節點 性能壓測

文章目錄 一、代碼說明1.1 主要功能1.2 代碼示例1.3 代碼解釋1.4 執行流程 二、結果分析三、參數解釋3.1 numWorkers 和 numRequests 說明3.2 使用場景 四、注意事項 最近搭建了一個TRON節點&#xff0c;同事不相信我的自建節點比官方更靠譜&#xff0c;咱們給他使用golang寫一…

如何成為一個專業的AI產品經理?

可以找專業的老師帶。 可以找專業的內容學。 可以多遇挫折并快速學習&#xff0c;屢敗屢戰&#xff0c;筆者本人從業AI十年有余&#xff0c;吃了不少苦&#xff0c;有過很多或成功或失敗的經歷。 成為一個專業的AI產品經理需要一系列專業知識和技能的積累&#xff0c;以及在…

axios - 簡 單 的 請 求 模 板

import {message } from ant-design-vue import axios from axios import {useUserStore } from @/store/modules/user import router from @/routerconst instance = axios.create({baseURL: http://192.168.110.171:5201,timeout: 5000, })* 請求攔截器 insta

切換Ubuntu開機的主題

要將Ubuntu系統的啟動畫面&#xff08;即開機時的顯示界面&#xff09;從Lubuntu切換回原生的Ubuntu界面&#xff0c;可以按照以下步驟操作&#xff1a; 1. 安裝原生Ubuntu的plymouth主題 首先&#xff0c;確保你已經安裝了原生Ubuntu的plymouth主題。打開終端并運行以下命令…

基于Matlab卷積神經網絡(CNN)人臉識別系統

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 一、項目背景與意義 人臉識別技術作為計算機視覺領域的一個重要分支&#xff0c;已經廣泛應用于安全監控、身份驗證…

Python基礎知識歸納總結

目錄 一、線性表 總結 二、棧 三、隊列 四、哈希表 五、字符串 六、正則表達式 綜合示例 一、線性表 線性表&#xff08;通常用列表表示&#xff09;是一種按線性順序存儲元素的數據結構。 插入元素 (append, insert) 刪除元素 (remove, pop) 查找元素 (index) 更新…

FreeRTOS學習——FreeRTOS隊列(下)之隊列創建

本篇文章記錄我學習FreeRTOS隊列創建的知識。主要分享隊列創建需要使用的初始化函數、隊列復位函數。 需要進一步了解FreeRTOS隊列的相關知識&#xff0c;讀者可以參考以下文章&#xff1a; FreeRTOS學習——FreeRTOS隊列&#xff08;上&#xff09;_freertos 單元素隊列-CSDN博…