組合模式及C++程式碼實現
阿新 • • 發佈:2019-02-10
理論學習:
在開發中,我們經常可能要遞迴構建樹狀的組合結構,組合模式則提供了很好的解決方案!
比如下面我寫的一個程式,我們都知道重點大學可分為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++程式碼實現:
在開發中,我們經常可能要遞迴構建樹狀的組合結構,組合模式則提供了很好的解決方案!
組合模式的標準定義:將物件組合成樹形結構以表示“部分整體”的層次結構。組合模式使得使用者對單個物件和組合物件的使用具有一致性!組合模式解耦了客戶程式與複雜元素內部結構,從而使客戶程式可以像處理簡單元素一樣處理複雜元素。(具體內涵解讀請看下面的例項分析!)
例項分析:比如下面我寫的一個程式,我們都知道重點大學可分為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; }