詳解C/C++中低耦合代碼的設(shè)計(jì)實(shí)現(xiàn)
在我們?cè)O(shè)計(jì)C/C++ 程序的時(shí)候,有時(shí)需要兩個(gè)類或者兩個(gè)模塊相互“認(rèn)識(shí)”,或者兩個(gè)模塊間函數(shù)互相調(diào)用,假設(shè)我們正在開發(fā)一個(gè)網(wǎng)上商店,代表的網(wǎng)店客戶的類必須要知道相關(guān)的賬戶。
UML圖如下,這被稱為環(huán)依賴,這兩個(gè)類直接或間接地相互依賴。
一般我們都會(huì)采用結(jié)構(gòu)體或類前置聲明的方式,在解決此問題。
customer.h
#ifndef CUSTOMER_H_ #define CUSTOMER_H_ class Account; class Customer { // ... void setAccount(Account* account); { customerAccount = account; } //... private: Account* customerAccount; }; #endif
account.h
#ifndef ACCOUNT_H_ #define ACCOUNT_H_ class Customer; class Account { public: //... void setOwer(Customer* customer) { ower = customer; } //... private: Customer* ower; } #endif
老實(shí)說上面的方式確實(shí)可以消除編譯器的錯(cuò)誤,但是這種解決方案不夠好。
下面的調(diào)用示例,存在一個(gè)問題,當(dāng)刪除Account的實(shí)例,Customer的實(shí)例仍然存在,且內(nèi)部的指向Account的指針為空。使用或解引用此指正會(huì)導(dǎo)致嚴(yán)重的問題。
#include "account.h" #include "customer.h" //... Account *account = new Accout{}; Customer *customer = new Customer{}; account->setOwer(customer); customer->setAccount(account);
那有沒有更好的做法呢,依賴倒置原則可以很好的解決此類問題。
依賴倒置原則
第一步是我們不在兩個(gè)類中的其中一個(gè)訪問另一個(gè),相反,我們只通過接口進(jìn)行訪問。我們從Customer中提取Ower的接口,作為示例,Ower接口中聲明一個(gè)純虛函數(shù),該函數(shù)必須由此接口類覆蓋。
ower.h
#ifndef OWNER_H_ #define OWNER_H_ #include <memory> #include <string> class owner { public: virtual ~owner()=default; virtual std::string getName() const = 0; }; using OwnerPtr = std::shared_ptr<Owner>; #endif
Customer.h
#ifndef CUSTOMER_H_ #define CUSTOMER_H_ #include "Owner.h" #include "Account.h" class Customer:public Owner { public: void setAccount(AccountPtr account) { customerAccount = account; } virtual std::string getName() const override{ //return string } private: Account customerAccount; }; using CustomerPtr = std::shared_ptr<Customer>; #endif
account.h
#ifndef ACCOUNT_H_ #define ACCOUNT_H_ #include "Owner.h" class Account { public: void setOwner(OwnerPtr owner) { this->owner = owner; } private: OwnerPtr owner; }; using AccountPtr = std::shared_ptr<Account>;
現(xiàn)在設(shè)計(jì)完發(fā)現(xiàn)這兩個(gè)模塊間消除了環(huán)依賴。
C/C++ 通過回調(diào)函數(shù)和信號(hào)槽的方式降低模塊的耦合性
為了降低模塊功能代碼的耦合性,我們經(jīng)常采用回調(diào)函數(shù)或者信號(hào)槽的方式來聯(lián)系兩個(gè)模塊。
回調(diào)函數(shù)的方式:
a.h
#pragma once #ifndef A_H_ #define A_H_ #include <stdio.h> int test(int c); #endif
a.c
#include "a.h" int test(int c) { c = 0x11112; return c; }
b.h
#pragma once #ifndef B_H_ #define B_H_ #include <stdio.h> typedef int (*PtrFunA)(int); int testb(PtrFunA, int c); #endif
b.c
#include "b.h" int testb(PtrFunA a, int c) { int ret = a(c); printf("%d\n", ret); return ret; }
main.c
#include <stdio.h> #include "a.h" #include "b.h" int main() { testb(test,123); }
這樣做的好處降低代碼的耦合性,是A模塊的功能代碼只寫在A.C中。B.C的功能代碼只寫在B.C中,改進(jìn)的后的回調(diào)函數(shù)可以用void*進(jìn)行傳參,在a.c中對(duì)void*進(jìn)行判斷,這是很多代碼常做的操作。
信號(hào)槽的話則更加靈活性和代碼的耦合度再次降低,后期在說,先寫在這了。
以上就是詳解C/C++中低耦合代碼的設(shè)計(jì)實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于C++低耦合代碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++實(shí)現(xiàn)算法兩個(gè)數(shù)字相加詳解
這篇文章主要介紹了C++實(shí)現(xiàn)算法兩個(gè)數(shù)字相加詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07簡述C語言中system()函數(shù)與vfork()函數(shù)的使用方法
這篇文章主要介紹了簡述C語言中system()函數(shù)與vfork()函數(shù)的使用方法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08C語言嵌入式實(shí)現(xiàn)支持浮點(diǎn)輸出的printf示例詳解
這篇文章主要為大家介紹了C語言嵌入式實(shí)現(xiàn)支持浮點(diǎn)輸出的printf示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01C++?OpenCV實(shí)現(xiàn)boxfilter方框?yàn)V波的方法詳解
box?filter的作用很簡單,即對(duì)局部區(qū)域求平均,并把值賦給某個(gè)點(diǎn),一般我們賦給區(qū)域中心。本文將用C++實(shí)現(xiàn)boxfilter方框?yàn)V波,需要的可以了解一下2022-10-10詳解圖的應(yīng)用(最小生成樹、拓?fù)渑判?、關(guān)鍵路徑、最短路徑)
這篇文章主要介紹了圖的應(yīng)用(最小生成樹、拓?fù)渑判?、關(guān)鍵路徑、最短路徑),需要的朋友可以參考下2015-08-08