1. 程式人生 > >組合模式及C++程式碼實現

組合模式及C++程式碼實現

理論學習:
        在開發中,我們經常可能要遞迴構建樹狀的組合結構,組合模式則提供了很好的解決方案!

        組合模式的標準定義:將物件組合成樹形結構以表示“部分整體”的層次結構。組合模式使得使用者對單個物件和組合物件的使用具有一致性!組合模式解耦了客戶程式與複雜元素內部結構,從而使客戶程式可以像處理簡單元素一樣處理複雜元素。(具體內涵解讀請看下面的例項分析!)

例項分析:
       比如下面我寫的一個程式,我們都知道重點大學可分為985重點大學和211重點大學,每所大學都有屬於自己的學院,如機械工程學院、土木工程學院、人文學院等!重點大學的各學院的拓撲圖就是一個樹形結構。在程式中,M_University 作為中間結點,可以有新增函式(新增函式使用C++中的容器vector實現!),Ji_Xie、Tu_Mu、 Ren_Wen這些類作為葉子結點,新增函式沒有意義,定義為空。在主函式中,向重點大學裡面新增重點大學機械工程學院、重點大學土木工程學院、重點大學人文學院這些物件時是一一新增進去的!而向重點大學裡面新增985重點大學物件和211重點大學物件時,是分別把他們作為組合物件新增進去的! 985重點大學作為一個組合物件包括985重點大學機械工程學院、985重點大學土木工程學院、985重點大學人文學院!211重點大學作為一個組合物件包括211重點大學機械工程學院、211重點大學土木工程學院、 211重點大學人文學院!    
       在主函式中向重點大學裡面新增985重點大學這個組合物件和新增211重點大學這個組合物件,其方法和向重點大學裡面新增簡單的元素:重點大學機械工程學院、重點大學土木工程學院、重點大學人文學院一樣,前者和後者使用的都是Add方法!這就驗證了組合模式的核心思想:使得使用者對單個物件和組合物件的使用具有一致性!使客戶程式可以像處理簡單元素一樣處理複雜元素!


組合模式的C++程式碼實現:
#include<iostream>
#include<string>
#include<vector>
using namespace std;

class University //抽象類,大學
{
public:
	University(string name)
	{
		this->name = name;
	}
	virtual void Add(University*pUniversity) = 0; //新增函式的抽象介面
	virtual void show() = 0;//顯示函式的抽象介面
protected:
	string name;
};

//具體類,大學(中間結點)
class M_University :public University
{
public:
	M_University(string name) :University(name){}

	virtual void Add(University*pUniversity)//中間結點,Add方法有意義
	{
		m_University.push_back(pUniversity);//往容器m_University中新增物件
	}

	virtual void show()//中間結點,不僅要顯示本層結點還要顯示本層結點的下層結點
	{
		cout << name << endl;//顯示本層結點
		vector<University*>::iterator iter = m_University.begin();//定義迭代器iter指向m_University容器中的第一個元素
		for (; iter != m_University.end(); ++iter)//顯示本層結點的所有下層結點
		{
			(*iter)->show();
		}
	}
private:
	vector<University*> m_University; //定義一個存放University*類物件的容器m_University 
};

//具體學院,機械工程學院(葉子結點)
class Ji_Xie :public University
{
public:
	Ji_Xie(string name) :University(name){}

	virtual void Add(University*pUniversity){}//葉子結點,Add方法沒有意義,定義為空

	virtual void show() //葉子結點,只需顯示本層結點的內容
	{
		cout << name << endl;
	}
};

//具體學院,土木工程學院(葉子結點)
class Tu_Mu :public University
{
public:
	Tu_Mu(string name) :University(name){}

	virtual void Add(University*pUniversity){}//葉子結點,Add方法沒有意義,定義為空

	virtual void show() //葉子結點,只需顯示本層結點的內容
	{
		cout << name << endl;
	}
};

//具體學院,人文學院(葉子結點)
class Ren_Wen :public University
{
public:
	Ren_Wen(string name) :University(name){}

	virtual void Add(University*pUniversity){}//葉子結點,Add方法沒有意義,定義為空

	virtual void show() //葉子結點,只需顯示本層結點的內容
	{
		cout << name << endl;
	}
};

int main(void)
{
	University*root = new M_University("重點大學");
	University*leaf1 = new Ji_Xie("重點大學的機械工程學院");
	University*leaf2 = new Tu_Mu("重點大學的土木工程學院");
	University*leaf3 = new  Ren_Wen("重點大學的人文學院");
	root->Add(leaf1);
	root->Add(leaf2);
	root->Add(leaf3);

	University*mid1 = new M_University("985重點大學");
	University*leaf4 = new Ji_Xie("985重點大學的機械工程學院");
	University*leaf5 = new Tu_Mu("985重點大學的土木工程學院");
	University*leaf6 = new Ren_Wen("985重點大學的人文學院");
	mid1->Add(leaf4);
	mid1->Add(leaf5);
	mid1->Add(leaf6);
	root->Add(mid1);

	University*mid2 = new M_University("211重點大學");
	University*leaf7 = new Ji_Xie("211重點大學的機械工程學院");
	University*leaf8 = new Tu_Mu("211重點大學的土木工程學院");
	University*leaf9 = new Ren_Wen("211重點大學的人文學院");
	mid2->Add(leaf7);
	mid2->Add(leaf8);
	mid2->Add(leaf9);
	root->Add(mid2);
	root->show();
	cout << endl;
	delete root; delete mid1; delete mid2;
	delete leaf1;
	delete leaf2;
	delete leaf3;
	delete leaf4;
	delete leaf5;
	delete leaf6;
	delete leaf7;
	delete leaf8;
	delete leaf9;
	system("pause");
	return 0;
}