欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中的策略模式淺析

 更新時(shí)間:2023年02月27日 08:58:53   作者:北冥有魚(yú)丶丶  
策略模式屬于C++設(shè)計(jì)模式中行為模式之一,該模式定義了一系列算法,并將每個(gè)算法封裝起來(lái),使它們可以相互替換。本文將通過(guò)示例詳細(xì)講解這一模式,需要的可以參考一下

策略模式主要解決在有多種算法相似的情況下,使用 if…else 所帶來(lái)的復(fù)雜和難以維護(hù),其實(shí)際就是用來(lái)抽象變化的(和開(kāi)放-封閉原則是一個(gè)原理),只要在分析過(guò)程中我們發(fā)現(xiàn)需要在不同的時(shí)間運(yùn)用不同類(lèi)型的業(yè)務(wù)規(guī)則或者代碼中可能會(huì)出現(xiàn)很多變化,就可以考慮使用策略模式來(lái)處理這種變化。

策略模式通常的使用方法就是一個(gè)抽象策略類(lèi),若干具體策略類(lèi)和一個(gè)Context類(lèi),同時(shí)Conetext類(lèi)可以結(jié)合簡(jiǎn)單工廠(chǎng)模式讓用戶(hù)與策略類(lèi)完全解耦,比如可以向Context類(lèi)的構(gòu)造函數(shù)中傳入?yún)?shù)而不是策略類(lèi),然后在Conext的構(gòu)造函數(shù)里用簡(jiǎn)單工廠(chǎng)模式根據(jù)傳遞的參數(shù)初始化策略類(lèi),甚至還可以什么都不傳,定義一個(gè)默認(rèn)策略供用戶(hù)使用(簡(jiǎn)單工廠(chǎng)不一定是要一個(gè)單獨(dú)的類(lèi))。Conetext類(lèi)中包含一個(gè)策略類(lèi)的指針指向簡(jiǎn)單工廠(chǎng)實(shí)例化出的具體策略類(lèi)對(duì)象,還包含一個(gè)contextDeloy接口用于通過(guò)策略類(lèi)指針去調(diào)用實(shí)例化出的具體策略類(lèi)對(duì)象的接口,可以讓用戶(hù)面對(duì)Context的接口編程,而不與策略類(lèi)接口直接耦合 ,方便策略類(lèi)日后更改接口,同時(shí)還需要一個(gè)get接口,用于獲取簡(jiǎn)單工廠(chǎng)中實(shí)例化出的對(duì)象。在業(yè)務(wù)邏輯層,我們先判斷簡(jiǎn)單工廠(chǎng)模式實(shí)例化的具體對(duì)象是否為空,如果不為空,我們就可以通過(guò)contextDeloy接口去訪(fǎng)問(wèn)實(shí)例化的具體策略類(lèi)對(duì)象的接口。

其實(shí)之前的這篇博客https://blog.csdn.net/weixin_44049823/article/details/128907849中,計(jì)算器5.0版本就已經(jīng)使用了策略模式,在這篇博客中,我們共實(shí)現(xiàn)了計(jì)算器的5個(gè)版本,最初使用的是簡(jiǎn)單粗暴的if-else-if語(yǔ)句來(lái)判斷使用哪一種業(yè)務(wù)(運(yùn)算),到5.0版本,我們抽象出了一個(gè)Operation類(lèi)(策略類(lèi)),然后又創(chuàng)建了4個(gè)具體類(lèi),加法運(yùn)算、減法運(yùn)算、乘法運(yùn)算、除法運(yùn)算類(lèi)(4個(gè)具體策略類(lèi)),最后創(chuàng)建了一個(gè)工廠(chǎng)類(lèi)用于根據(jù)不同情況實(shí)例化不同運(yùn)算類(lèi)的對(duì)象,其實(shí)這之中的一個(gè)抽象策略類(lèi)和4個(gè)具體策略類(lèi)已經(jīng)有策略模式的影子了,但是缺少了其精華Context類(lèi)。

接下來(lái)我將用策略模式改寫(xiě)之前的計(jì)算器5.0版本。

#include<iostream>
using namespace std;
#include<string>
//業(yè)務(wù)邏輯
//異常類(lèi)用于處理異常情況
class opeException
{
public:
	void getMessage()
	{
		cout << "您的輸入有誤!" << endl;
	}
};
//運(yùn)算類(lèi)
class Operation
{
	//判斷一個(gè)字符串是不是數(shù)字
	bool isStringNum(string& s)
	{
		bool flag = true;
		for (auto e : s)
			if (!(isdigit(e)))
			{
				flag = false;
				break;
			}
		return flag;
	}
protected:
	bool isError(string& _strNum1, string& _strNum2, string& _ope)
	{
		if (!(Operation::isStringNum(_strNum1) && Operation::isStringNum(_strNum2) && (_ope == "+" || _ope == "-" || _ope == "*" || _ope == "/")))
		{
			return false;
		}
	}
public:
	virtual int getResult()
	{
		return 0;
	}
};
//加法運(yùn)算類(lèi)
class addOperation :public Operation
{
private:
	string strNum1;
	string strNum2;
	string ope;
	int re;
public:
	addOperation(string& _strNum1, string& _strNum2, string& _ope) :strNum1(_strNum1), strNum2(_strNum2), ope(_ope), re(0) {}
	virtual int getResult() override
	{
		if (!isError(strNum1, strNum2, ope))
			throw opeException();
		else
			re = stoi(strNum1) + stoi(strNum2);
		return re;
	}
};
//減法運(yùn)算類(lèi)
class subOperation :public Operation
{
private:
	string strNum1;
	string strNum2;
	string ope;
	int re;
public:
	subOperation(string& _strNum1, string& _strNum2, string& _ope) :strNum1(_strNum1), strNum2(_strNum2), ope(_ope), re(0) {}
	virtual int getResult() override
	{
		if (!isError(strNum1, strNum2, ope))
			throw opeException();
		else
			re = stoi(strNum1) - stoi(strNum2);
		return re;
	}
};
//乘法運(yùn)算類(lèi)
class mulOperation :public Operation
{
private:
	string strNum1;
	string strNum2;
	string ope;
	int re;
public:
	mulOperation(string& _strNum1, string& _strNum2, string& _ope) :strNum1(_strNum1), strNum2(_strNum2), ope(_ope), re(0) {}
	virtual int getResult() override
	{
		if (!isError(strNum1, strNum2, ope))
			throw opeException();
		else
			re = stoi(strNum1) * stoi(strNum2);
		return re;
	}
};
//除法運(yùn)算類(lèi)
class divOperation :public Operation
{
private:
	string strNum1;
	string strNum2;
	string ope;
	int re;
public:
	divOperation(string& _strNum1, string& _strNum2, string& _ope) :strNum1(_strNum1), strNum2(_strNum2), ope(_ope), re(0) {}
	virtual int getResult() override
	{
		if (!isError(strNum1, strNum2, ope))
			throw opeException();
		else if (stoi(strNum2) != 0)
			re = stoi(strNum1) / stoi(strNum2);
		else
			throw opeException();
		return re;
	}
};
//Conetext結(jié)合簡(jiǎn)單工廠(chǎng)模式
class Context
{
	Operation *operation;
public:
	Context(string& _strNum1, string& _strNum2, string& _ope)
	{
		if (_ope == "+")
		{
			operation = new addOperation(_strNum1, _strNum2, _ope);
		}
		else if (_ope == "-")
			operation = new subOperation(_strNum1, _strNum2, _ope);
		else if (_ope == "*")
			operation = new mulOperation(_strNum1, _strNum2, _ope);
		else if (_ope == "/")
		{
			operation = new divOperation(_strNum1, _strNum2, _ope);
		}
		else
			operation = nullptr;
	}
	Operation* get()
	{
		return operation;
	}
	int contextResult()
	{
		return operation->getResult();
	}
};
//界面邏輯
int main()
{
	try
	{
		string _strNum1 = " ";
		string _strNum2 = " ";
		string _ope = " ";
		cout << "請(qǐng)輸入左操作數(shù):" << endl;
		cin >> _strNum1;
		cout << "請(qǐng)輸入右操作數(shù):" << endl;
		cin >> _strNum2;
		cout << "請(qǐng)輸入操作符:" << endl;
		cin >> _ope;
		Context context(_strNum1, _strNum2, _ope);
		if (context.get() != nullptr)
			cout << context.contextResult() << endl;
		else
			cout << "您的輸入有誤!" << endl;
	}
	catch (opeException ex)
	{
		cout << "您的輸入有誤" << endl;
	}
	return 0;
}

結(jié)合上一篇博客的5.0版本代碼可知,簡(jiǎn)單工廠(chǎng)模式需要讓客戶(hù)端認(rèn)識(shí)兩個(gè)類(lèi),而策略類(lèi)只需要讓客戶(hù)端認(rèn)識(shí)一個(gè)類(lèi)即可,耦合更低。

總結(jié)策略模式的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

1、算法可以自由切換。

2、避免使用多重條件判斷。

3、擴(kuò)展性良好。

缺點(diǎn):

1、策略類(lèi)會(huì)增多。

2、所有策略類(lèi)都需要對(duì)外暴露。

注意事項(xiàng):如果一個(gè)系統(tǒng)的策略多于四個(gè),就需要考慮使用混合模式,解決策略類(lèi)膨脹的問(wèn)題。

到此這篇關(guān)于C++中的策略模式淺析的文章就介紹到這了,更多相關(guān)C++策略模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)單詞小幫手

    C語(yǔ)言實(shí)現(xiàn)單詞小幫手

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)單詞小幫手,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 詳解如何將Spire.PDF for C++集成到C++程序中

    詳解如何將Spire.PDF for C++集成到C++程序中

    Spire.PDF for C++ 是一個(gè)專(zhuān)業(yè)的 PDF 庫(kù),供開(kāi)發(fā)人員在任何類(lèi)型的 C++ 應(yīng)用程序中閱讀、創(chuàng)建、編輯和轉(zhuǎn)換 PDF 文檔,本文主要介紹了兩種不同的方式將 Spire.PDF for C++ 集成到您的 C++ 應(yīng)用程序中,希望對(duì)大家有所幫助
    2023-11-11
  • C經(jīng)典冒泡排序法實(shí)現(xiàn)代碼

    C經(jīng)典冒泡排序法實(shí)現(xiàn)代碼

    這篇文章主要介紹了C經(jīng)典冒泡排序法實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2014-02-02
  • QT5?Thread線(xiàn)程的具體實(shí)現(xiàn)

    QT5?Thread線(xiàn)程的具體實(shí)現(xiàn)

    本文主要介紹了QT5?Thread線(xiàn)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C++中的opeartor?new和placement?new使用步驟

    C++中的opeartor?new和placement?new使用步驟

    這篇文章主要介紹了C++中的opeartor?new和placement?new詳解,在很多情況下,placement?new的使用方法和其他普通的new有所不同。這里提供了它的使用步驟,需要的朋友可以參考下
    2022-10-10
  • C語(yǔ)言版三子棋游戲?qū)崿F(xiàn)代碼

    C語(yǔ)言版三子棋游戲?qū)崿F(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言版三子棋游戲的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C語(yǔ)言實(shí)現(xiàn)對(duì)bmp格式圖片打碼

    C語(yǔ)言實(shí)現(xiàn)對(duì)bmp格式圖片打碼

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)對(duì)bmp格式圖片打碼
    2016-01-01
  • C++類(lèi)中隱藏的幾個(gè)默認(rèn)函數(shù)你知道嗎

    C++類(lèi)中隱藏的幾個(gè)默認(rèn)函數(shù)你知道嗎

    這篇文章主要為大家詳細(xì)介紹了C++類(lèi)中隱藏的幾個(gè)默認(rèn)函數(shù),使用數(shù)據(jù)庫(kù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼

    C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼

    本文主要介紹了C語(yǔ)言模擬實(shí)現(xiàn)密碼輸入的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 一般函數(shù)指針和類(lèi)的成員函數(shù)指針深入解析

    一般函數(shù)指針和類(lèi)的成員函數(shù)指針深入解析

    以下是對(duì)一般函數(shù)指針和類(lèi)的成員函數(shù)指針進(jìn)行了介紹。需要的朋友可以過(guò)來(lái)參考下
    2013-08-08

最新評(píng)論