從兩個排序算法實現c++策略模式

簡介


所謂策略,是指一系列的操作。

比如古代打仗,可以直接雙方對壘派兵廝打,也可以等到月明星稀偷營劫寨,還可以略施小計。這些都是策略。

又比如計算稅費時,不同國家的計算方法是不同的。如美國的10%,日本的8%,歐萌的12%…等,這些也都是策略。

策略模式,就是把一個個的策略封裝起來,並且使它們可以相互替換。以達到算法獨立於客戶的目的。這樣可以在不改變客戶的情況下靈活地變更各種策略(算法)。

策略模式的目的就是爲了適應不同的需求,把這些容易變化的點(不同策略之間可能會互換)封裝起來。這樣就能夠在不變更原有代碼的情況下擴展需求。

本文以實現兩種不再的排序算法爲例實現策略模式。

不使用策略模式


首先看看不使用策略模式的方法。

現在需要設計一個升序排序算法:比較兩個數字,if a<b, return a。

class AsscendingSortAlgo
{
	void swap(int &x, int &y)
	{
		int tmp = x;
		x = y;
		y = tmp;
	}
	
	bool comparisionLogic(int a, int b)
	{
		if(a > b)
			return true;
		else
			return false;
	}
	
public:
	void sort(std::vector<int> &arr) 
	{
		bool isSwapped = true;
		int x = 0;
		while (isSwapped)
		{
			isSwapped = false;
			x++;
			for (int i = 0; i < arr.size() - x; i++)
			{
				if (comparisionLogic(arr[i] , arr[i + 1]) )
				{
					swap(arr[i], arr[i + 1]);
					isSwapped = true;
				}
			}
		}
	}
};

現在又增加了一個新需求:降序排序算法:比較兩個數字,if a<b, return b。

class DessendingSortAlgo
{
	void swap(int &x, int &y)
	{
		int tmp = x;
		x = y;
		y = tmp;
	}
	
	bool comparisionLogic(int a, int b)
	{
		if(a < b)
			return true;
		else
			return false;
	}
	
public:
	void sort(std::vector<int> & arr) 
	{
		bool isSwapped = true;
		int x = 0;
		while (isSwapped)
		{
			isSwapped = false;
			x++;
			for (int i = 0; i < arr.size() - x; i++)
			{
				if (comparisionLogic(arr[i] , arr[i + 1]) )
				{
					swap(arr[i], arr[i + 1]);
					isSwapped = true;
				}
			}
		}
	}
};

就是這樣,當算法與與策略緊密耦合時,一旦需求發生變化,就需要設計不同的新類。

這無疑會增加編碼和測試的難度,每次改動原有的代碼,哪怕只是一個字符,也需要對原有系統進行全面的測試。

如何解決這個問題?

策略模式


實現策略模式的步驟:

  1. 創建抽象策略接口定義行爲
  2. 從抽象策略接口繼承實現具體策略
  3. 創建算法類,在算法類內使用指針或引用與策略松耦合
  4. 運行時指定具體策略

在這裏插入圖片描述

開始實現我們的策略模式:

在這裏插入圖片描述

  • 創建抽象策略接口
class IComparator
{
public:
	virtual bool compare(int a, int b) = 0;
	virtual ~IComparator(){}
};
  • 創建具體策略
class LesserComprataor : public IComparator
{
public:
	bool compare(int a, int b)
	{
		if(a > b)
			return true;
		else
			return false;
	}
};

class GreaterComprataor : public IComparator
{
public:
	bool compare(int a, int b)
	{
		if(a < b)
			return true;
		else
			return false;
	}
};
  • 創建算法類
class SortingAlgo
{
	IComparator * m_pComparator;
	void swap(int &x, int &y)
	{
		int tmp = x;
		x = y;
		y = tmp;
	}
	
public:
	SortingAlgo()
	{
		m_pComparator = new LesserComprataor();
	}
	
	void sort(std::vector<int> & arr, IComparator * pComparator = NULL)
	{
		if(pComparator == NULL)
				pComparator = m_pComparator;
				
		bool isSwapped = true;
		int x = 0;
		while (isSwapped)
		{
			isSwapped = false;
			x++;
			for (int i = 0; i < arr.size() - x; i++)
			{
				if (pComparator->compare(arr[i] , arr[i + 1]) )
				{
					swap(arr[i], arr[i + 1]);
					isSwapped = true;
				}
			}
		}
	}
};
  • 使用算法類,此時可以靈活地使用不同的策略
std::vector<int> arr = {1,5,2,4,3};
SortingAlgo obj;
IComparator * pComp = new LesserComprataor();
obj.sort(arr, pComp);
for (int var = 0; var < 5; ++var) 
{
	std::cout<<arr[var]<<" ";
}
std::cout<<std::endl;
delete pComp;
pComp = NULL;

pComp = new GreaterComprataor();
obj.sort(arr, pComp);
for (int var = 0; var < 5; ++var) 
{
	std::cout<<arr[var]<<" ";
}
std::cout<<std::endl;
delete pComp;
pComp = NULL;

obj.sort(arr);
for (int var = 0; var < 5; ++var) 
{
	std::cout<<arr[var]<<" ";
}
std::cout<<std::endl;
delete pComp;
pComp = NULL;

此時,使用了策略模式,就可以在靈活地決定使用何種算法。

增加一個新的算法時,也只需要少量的更改即可達到目的。

參考資料

Design Sorting algorithm using Strategy Design Pattern

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章