最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中的策略模式淺析

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

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

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

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

接下來我將用策略模式改寫之前的計算器5.0版本。

#include<iostream>
using namespace std;
#include<string>
//業(yè)務(wù)邏輯
//異常類用于處理異常情況
class opeException
{
public:
	void getMessage()
	{
		cout << "您的輸入有誤!" << endl;
	}
};
//運算類
class Operation
{
	//判斷一個字符串是不是數(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;
	}
};
//加法運算類
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;
	}
};
//減法運算類
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;
	}
};
//乘法運算類
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;
	}
};
//除法運算類
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é)合簡單工廠模式
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 << "請輸入左操作數(shù):" << endl;
		cin >> _strNum1;
		cout << "請輸入右操作數(shù):" << endl;
		cin >> _strNum2;
		cout << "請輸入操作符:" << 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版本代碼可知,簡單工廠模式需要讓客戶端認(rèn)識兩個類,而策略類只需要讓客戶端認(rèn)識一個類即可,耦合更低。

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

優(yōu)點:

1、算法可以自由切換。

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

3、擴展性良好。

缺點:

1、策略類會增多。

2、所有策略類都需要對外暴露。

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

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

相關(guān)文章

  • C++類的定義與實現(xiàn)

    C++類的定義與實現(xiàn)

    這篇文章主要介紹了C++類的定義與實現(xiàn),違章圍繞C++類的定義的相關(guān)資料展開全文內(nèi)容,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-01-01
  • 指針操作數(shù)組的兩種方法(總結(jié))

    指針操作數(shù)組的兩種方法(總結(jié))

    下面小編就為大家?guī)硪黄羔槻僮鲾?shù)組的兩種方法(總結(jié))。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • UE4 Unlua 調(diào)用異步藍(lán)圖節(jié)點AIMoveTo函數(shù)示例詳解

    UE4 Unlua 調(diào)用異步藍(lán)圖節(jié)點AIMoveTo函數(shù)示例詳解

    這篇文章主要為大家介紹了UE4 Unlua 調(diào)用AIMoveTo函數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • C語言合并排序及實例代碼

    C語言合并排序及實例代碼

    本篇文章主要介紹C語言合并排序算法,這里對合并排序通過實例代碼進(jìn)行了詳細(xì)講解,希望能幫助到大家學(xué)習(xí)
    2016-07-07
  • c++帶有string的結(jié)構(gòu)體賦值和清零問題

    c++帶有string的結(jié)構(gòu)體賦值和清零問題

    這篇文章主要介紹了c++帶有string的結(jié)構(gòu)體賦值和清零問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • C++詳解實現(xiàn)Stack方法

    C++詳解實現(xiàn)Stack方法

    C++ Stack(堆棧)是一個容器類的改編,為程序員提供了堆棧的全部功能,也就是說實現(xiàn)了一個先進(jìn)后出(FILO)的數(shù)據(jù)結(jié)構(gòu)
    2022-06-06
  • VS2019配置opencv詳細(xì)圖文教程和測試代碼的實現(xiàn)

    VS2019配置opencv詳細(xì)圖文教程和測試代碼的實現(xiàn)

    這篇文章主要介紹了VS2019配置opencv詳細(xì)圖文教程和測試代碼的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • C語言中的abs()函數(shù)和exp()函數(shù)的用法

    C語言中的abs()函數(shù)和exp()函數(shù)的用法

    這篇文章主要介紹了C語言中的abs()函數(shù)和exp()函數(shù)的用法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-08-08
  • QT中窗口關(guān)閉自動銷毀的實現(xiàn)示例

    QT中窗口關(guān)閉自動銷毀的實現(xiàn)示例

    這篇文章主要介紹了QT中窗口關(guān)閉自動銷毀,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 利用Matlab繪制一個可愛的南瓜燈

    利用Matlab繪制一個可愛的南瓜燈

    這篇文章主要為大家介紹了如何利用Matlab繪制一個可愛的南瓜燈!文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Matlab有一定幫助,需要的可以參考一下
    2022-02-02

最新評論

南部县| 天峻县| 台东县| 西丰县| 莱州市| 阿克陶县| 岑溪市| 鹿泉市| 临汾市| 冀州市| 汾西县| 大同县| 府谷县| 德安县| 平山县| 绵竹市| 青浦区| 南充市| 东平县| 阿巴嘎旗| 奉新县| 云浮市| 关岭| 曲阜市| 遂昌县| 平武县| 增城市| 白河县| 隆安县| 乌海市| 榕江县| 那坡县| 革吉县| 玉山县| 介休市| 大渡口区| 奉贤区| 永寿县| 定结县| 舒城县| 博乐市|