首頁 > 軟體

C++設計模式中控制反轉與依賴注入淺析

2023-01-14 14:00:34

控制反轉

“控制”指的是對程式執行流程的控制,而“反轉”指的是在沒有使用框架之前,程式設計師自己控制整個程式的執行。在使用框架之後,整個程式的執行流程可以通過框架來控制。流程的控制權從程式設計師“反轉”到了框架。

大白話說,就是原先直接用main函數中的程式碼流程,轉移到了框架中去。

#include <iostream>
#include <list>
using namespace std;
class TestCase
{
public:
	TestCase() {};
	~TestCase() {};
	virtual int test() = 0;
	void run()
	{
		switch (test())
		{
		case 1:cout << "1 test() " << endl; break;
		case 2:cout << "2 test() " << endl; break;
		default:
			break;
		}
	}
};
class Cases : public TestCase
{
	virtual int test() override
	{
		return 1;
	}
};
class Dases : public TestCase
{
	virtual int test() override
	{
		return 2;
	}
};
class Application
{
public:
	void registers(TestCase *cases)
	{
		testCases.push_back(cases);
	}
	void runStage()
	{
		for (auto&it : testCases)
		{
			it->run();
		}
	}
private:
	list<TestCase*> testCases;
};
int main()
{
    std::cout << "Hello World!n";
	TestCase *case1 = new Cases();
	TestCase *dase1 = new Dases();
	Application app;
	app.registers(case1);
	app.registers(dase1);
	app.runStage();
}

依賴注入(DI)

什麼是依賴注入呢?

概括就是:不通過 new() 的方式在類內部建立依賴類物件,而是將依賴的類物件在外部建立好之後,通過建構函式、函數引數等方式傳遞(或注入)給類使用。

class Message
{
public:
	virtual void send(string msg) = 0;
};
class phoneMessage : public Message
{
public:
	virtual void send(string msg) override
	{
		cout << "this is phone msg : " << msg.c_str() << endl;
	}
private:
};
class NotifyIterface
{
public:
	NotifyIterface(Message *obj)
	{
		message = obj;
	}
	void sendMsg(string msg)
	{
		message->send(msg);
	}
private:
	Message *message;
};
class MessageSender
{
public:
	void sender(string msg)
	{
		cout << msg.c_str() << endl;
	}
};
//非依賴注入
class Notification
{
public:
	Notification()
	{
		msgsender = new MessageSender();
	}
	void sendMsg(string msg)
	{
		msgsender->sender(msg);
	}
private:
	MessageSender *msgsender;
};
//依賴注入
class Notification2
{
public:
	Notification2(MessageSender *obj)
	{
		msgsender = obj;
	}
	void sendMsg(string msg)
	{
		msgsender->sender(msg);
	}
private:
	MessageSender *msgsender;
};
int main()
{
	//非依賴注入的寫法
	Notification *notify = new Notification();
	notify->sendMsg("this is not DI");
	//依賴注入的寫法,通過依賴注入的方式來將依賴的類物件傳遞進來,這樣就提高了程式碼的擴充套件性
	MessageSender *msgobj = new MessageSender();
	Notification2 *notify2 = new Notification2(msgobj);
	notify2->sendMsg("this is DI");
	//依賴注入,改為通過介面實現
	Message *message = new phoneMessage();
	NotifyIterface *notifyIterface = new NotifyIterface(message);
	notifyIterface->sendMsg(" Iphone !");
}

依賴注入框架(DI Framework)

在採用依賴注入實現的 Notification 類中,雖然我們不需要用類似 hard code 的方式,在類內部通過 new 來建立 MessageSender 物件,但是,這個建立物件、組裝(或注入)物件的工作僅僅是被移動到了更上層程式碼而已,還是需要我們程式設計師自己來實現。

物件建立和依賴注入的工作,本身跟具體的業務無關,我們完全可以抽象成框架來自動完成。

實際上,現成的依賴注入框架有很多,比如 Google Guice、Java Spring、Pico Container、Butterfly Container 等。不過,如果你熟悉 Java Spring 框架,你可能會說,Spring 框架自己聲稱是控制反轉容器(Inversion Of Control Container)。

不過這一塊兒的東西先做了解,具體的實現需要自己想一想再去實現。

依賴反轉原則(DIP)

高層模組(high-level modules)不要依賴低層模組(low-level)。高層模組和低層模組應該通過抽象(abstractions)來互相依賴。除此之外,抽象(abstractions)不要依賴具體實現細節(details),具體實現細節(details)依賴抽象(abstractions)。

所謂高層模組和低層模組的劃分,簡單來說就是,在呼叫鏈上,呼叫者屬於高層,被呼叫者屬於低層。在平時的業務程式碼開發中,高層模組依賴底層模組是沒有任何問題的。

依賴反轉原則也叫作依賴倒置原則。這條原則跟控制反轉有點類似,主要用來指導框架層面的設計。高層模組不依賴低層模組,它們共同依賴同一個抽象。抽象不要依賴具體實現細節,具體實現細節依賴抽象。

到此這篇關於C++設計模式中控制反轉與依賴注入淺析的文章就介紹到這了,更多相關C++控制反轉與依賴注入內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com