c++ 實現策略模式

策略模式(Strategy):它定義了算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化,不會影響到使用算法的客戶。

上面是《大話設計模式》中給出的定義,感覺這個概念給的不好,看了之後不能完全清晰明白該模式(可能自己水平太水的原因吧)。在《effective c++》中指出,策略模式是virtual 函數的替換方法。仔細想想也差不多。如果想在不同的類中實現不同的算法,那麼在基類中定義一個virtual函數,派生類給出不同的實現即可。這裏出現一個問題,如果要實現的算法太多(算法參數、返回值等不同),那麼需要在基類中都進行virtual聲明,在具體的類中給出具體函數的實現。那麼每個派生類都需要繼承那麼多virtual 函數(而且多數沒用),派生類好臃腫啊。有人給出派生類減肥法,工廠模式,其實就是每個算法給出一個實現類外加多態的使用;別的方法,那就是每個算法實現一個類,把這個類傳入到具體的過程類中,讓算法類作爲過程類的一個屬性,可以根據要求進行設置,當然這個算法跟工廠模式有些相似處。(後面有兩者關係圖)

先描述一下應用場景吧,設計商場收費軟件,要求能夠滿足,不同的打折要求、不同的滿幾百送幾百的返利要求。比如:店慶打8折,國慶節滿300送100;

下面看一下,工廠模式和策略模式關係圖,看一下他們之間的差別:

工廠模式:


策略模式:



下面看一下傳統的策略模式的實現代碼:

#include<iostream>
#include<string>

using namespace std;

class CashSuper
{
public:
	virtual double acceptCash(double money) = 0;
};

class CashNormal : public CashSuper
{
public :
	double acceptCash(double money)
	{
		return money;
	}

};

class CashRebate : public CashSuper
{
public:
	CashRebate(double d = 1) : moneyRebate(d)
	{}
	double acceptCash(double money);
private:
	double moneyRebate; 

};

double CashRebate::acceptCash(double money)
{
	return money * moneyRebate;
}

class CashReturn : public CashSuper
{
public:
	CashReturn(double mc = 0.0, double mr = 0.0) : moneyCondition(mc), moneyReturn(mr)
	{}
	double acceptCash(double money);
private:
	double moneyCondition;
	double moneyReturn;
};

double CashReturn::acceptCash(double money)
{
	double result = money;
	if (money > moneyCondition)
		result = money - (int)(money / moneyCondition)* moneyReturn;
	return result;
}

class CashContext
{
public :
	CashContext(CashSuper *cashuper) : cs(cashuper)
	{}
	double GetResult(double money);
private:
	CashSuper *cs;
};

double CashContext::GetResult(double money)
{
	return cs->acceptCash(money);
}

上面的是傳統策略模式的實現代碼,但是隻是個框架,很好看,不中用;沒有具體環境執行。

下面是策略模式和工廠模式結合的代碼,情景如上所述:其中1代表:正常模式收費;     2代表:滿300送100;   3代表:打8折。

將上面的CashContext替換成ConcreteCashContext就可以直接運行了。

class ConcreteCashContext
{
public:
	ConcreteCashContext(int type);
	double GetResult(double money);
private:
	CashSuper *cs;
};

double ConcreteCashContext::GetResult(double money)
{
	return cs->acceptCash(money);
}

ConcreteCashContext::ConcreteCashContext(int type)
{
	switch(type)
	{
	case 1:
		cs = new CashNormal();
		break;
	case 2:
		cs = new CashReturn(300,100);
		break;
	case 3:
		cs = new CashRebate(0.8);
		break;
	default:
		cout << " cant not recognize the type " << endl;
	}

}



int main(int argc, char **argv)
{
	ConcreteCashContext *ccc = new ConcreteCashContext(2);
	double money = 850.45;
	cout << " The moeny is : " << money << endl;
	cout << "you have to pay : " << ccc->GetResult(money) << endl;
	system("pause");
	return 0;
}


參考:

1、《大話設計模式》

2、《effective c++》




發佈了40 篇原創文章 · 獲贊 6 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章