《C++新经典设计模式》之第11章 组合模式
组合模式.cpp
#include #include #include #include #include #include using namespace std;namespace ns1{class File {string m_sname; public:File(const string &name) : m_sname(name) {}void ShowName(const string &lvlstr) const {cout << lvlstr << "-" << m_sname << endl; }};class Dir {string m_sname; list<shared_ptr<File>> m_childFile; list<shared_ptr<Dir>> m_childDir; public:Dir(const string &name) : m_sname(name) {}public:void AddFile(const shared_ptr<File> &pfile) { m_childFile.push_back(pfile); }void AddDir(const shared_ptr<Dir> &pdir) { m_childDir.push_back(pdir); }void ShowName(const string &lvlstr) const {cout << lvlstr << "+" << m_sname << endl; for (auto iter = m_childFile.cbegin(); iter != m_childFile.cend(); ++iter)(*iter)->ShowName(lvlstr + ""); for (auto iter = m_childDir.cbegin(); iter != m_childDir.cend(); ++iter)(*iter)->ShowName(lvlstr + ""); }};}namespace ns2{class FileSystem {public:virtual ~FileSystem() {}virtual void ShowName(int level) const = 0; virtual int Add(const shared_ptr<FileSystem> &pfilesys) = 0;virtual int Remove(const shared_ptr<FileSystem> &pfilesys) = 0; };class File : public FileSystem {string m_sname; public:File(const string &name) : m_sname(name) {}void ShowName(int level) const{for (int i = 0; i < level; ++i) cout << "";cout << "-" << m_sname << endl;}int Add(const shared_ptr<FileSystem> &pfilesys) override { return -1; }int Remove(const shared_ptr<FileSystem> &pfilesys) override { return -1; }};class Dir : public FileSystem {string m_sname; list<shared_ptr<FileSystem>> m_child; public:Dir(const string &name) : m_sname(name) {}void ShowName(int level) const{for (int i = 0; i < level; ++i)cout << "";cout << "+" << m_sname << endl;for (auto iter = m_child.cbegin(); iter != m_child.cend(); ++iter)(*iter)->ShowName(level + 1);}int Add(const shared_ptr<FileSystem> &pfilesys) override{m_child.push_back(pfilesys);return 0;}int Remove(const shared_ptr<FileSystem> &pfilesys) override{m_child.remove(pfilesys);return 0;}};}namespace ns3{class Dir;class FileSystem {public:virtual void ShowName(int level) const = 0; virtual ~FileSystem() {}public:virtual Dir *ifCompositeObj() { return nullptr; }virtual int countNumOfFiles() const = 0; };class File : public FileSystem {string m_sname; public:File(const string &name) : m_sname(name) {}void ShowName(int level) const override{for (int i = 0; i < level; ++i)cout << "";cout << "-" << m_sname << endl;}public:int countNumOfFiles() const override { return 1; }};class Dir : public FileSystem{string m_sname; list<shared_ptr<FileSystem>> m_child; public:Dir(const string &name) : m_sname(name) {}void ShowName(int level) const override{for (int i = 0; i < level; ++i)cout << "";cout << "+" << m_sname << endl;for (auto iter = m_child.cbegin(); iter != m_child.cend(); ++iter)(*iter)->ShowName(level + 1);}int Add(const shared_ptr<FileSystem> &pfilesys){m_child.push_back(pfilesys);return 0;}int Remove(const shared_ptr<FileSystem> &pfilesys){m_child.remove(pfilesys);return 0;}public:Dir *ifCompositeObj() override { return this; }public:int countNumOfFiles() const override{int iNumOfFiles = 0;for (auto iter = m_child.cbegin(); iter != m_child.cend(); ++iter)iNumOfFiles += (*iter)->countNumOfFiles(); return iNumOfFiles;}};}namespace ns4{class Employee{string name;string dept;int salary;vector<shared_ptr<Employee>> subordinates;public:Employee(const string &m_name, const string &m_dept, int m_salary) : name(m_name), dept(m_dept), salary(m_salary) {}void add(const shared_ptr<Employee> &e) { subordinates.push_back(e); }void remove(const shared_ptr<Employee> &e){auto it = find(subordinates.cbegin(), subordinates.cend(), e);if (it != subordinates.cend())subordinates.erase(it);}const vector<shared_ptr<Employee>> &getSubordinates() const { return subordinates; }string toString(){return ("Employee :[ Name : " + name + ", dept : " + dept + ", salary :" + to_string(salary) + " ]");}};}int main(){#if 0using namespace ns1;shared_ptr<Dir> pdir1(new Dir("root"));shared_ptr<File> pfile1(new File("common.mk"));shared_ptr<File> pfile2(new File("config.mk"));shared_ptr<File> pfile3(new File("makefile"));shared_ptr<Dir> pdir2(new Dir("app"));shared_ptr<File> pfile4(new File("nginx.c"));shared_ptr<File> pfile5(new File("ngx_conf.c"));shared_ptr<Dir> pdir3(new Dir("signal"));shared_ptr<File> pfile6(new File("ngx_signal.c"));shared_ptr<Dir> pdir4(new Dir("_include"));shared_ptr<File> pfile7(new File("ngx_func.h"));shared_ptr<File> pfile8(new File("ngx_signal.h"));pdir1->AddFile(pfile1);pdir1->AddFile(pfile2);pdir1->AddFile(pfile3);pdir1->AddDir(pdir2);pdir2->AddFile(pfile4);pdir2->AddFile(pfile5);pdir1->AddDir(pdir3);pdir3->AddFile(pfile6);pdir1->AddDir(pdir4);pdir4->AddFile(pfile7);pdir4->AddFile(pfile8);pdir1->ShowName(""); #endif#if 0using namespace ns2;shared_ptr<FileSystem> pdir1(new Dir("root"));shared_ptr<FileSystem> pfile1(new File("common.mk"));shared_ptr<FileSystem> pfile2(new File("config.mk"));shared_ptr<FileSystem> pfile3(new File("makefile"));shared_ptr<FileSystem> pdir2(new Dir("app"));shared_ptr<FileSystem> pfile4(new File("nginx.c"));shared_ptr<FileSystem> pfile5(new File("ngx_conf.c"));shared_ptr<FileSystem> pdir3(new Dir("signal"));shared_ptr<FileSystem> pfile6(new File("ngx_signal.c"));shared_ptr<FileSystem> pdir4(new Dir("_include"));shared_ptr<FileSystem> pfile7(new File("ngx_func.h"));shared_ptr<FileSystem> pfile8(new File("ngx_signal.h"));pdir1->Add(pfile1);pdir1->Add(pfile2);pdir1->Add(pfile3);pdir1->Add(pdir2);pdir2->Add(pfile4);pdir2->Add(pfile5);pdir1->Add(pdir3);pdir3->Add(pfile6);pdir1->Add(pdir4);pdir4->Add(pfile7);pdir4->Add(pfile8);pdir1->ShowName(0);#endif#if 0using namespace ns3;shared_ptr<Dir> pdir1(new Dir("root"));shared_ptr<FileSystem> pfile1(new File("common.mk"));shared_ptr<FileSystem> pfile2(new File("config.mk"));shared_ptr<FileSystem> pfile3(new File("makefile"));shared_ptr<Dir> pdir2(new Dir("app"));if (pdir2->ifCompositeObj() != nullptr){}if (dynamic_pointer_cast<Dir>(pdir2) != nullptr){}shared_ptr<FileSystem> pfile4(new File("nginx.c"));shared_ptr<FileSystem> pfile5(new File("ngx_conf.c"));shared_ptr<Dir> pdir3(new Dir("signal"));shared_ptr<FileSystem> pfile6(new File("ngx_signal.c"));shared_ptr<Dir> pdir4(new Dir("_include"));shared_ptr<FileSystem> pfile7(new File("ngx_func.h"));shared_ptr<FileSystem> pfile8(new File("ngx_signal.h"));pdir1->Add(pfile1);pdir1->Add(pfile2);pdir1->Add(pfile3);pdir1->Add(pdir2);pdir2->Add(pfile4);pdir2->Add(pfile5);pdir1->Add(pdir3);pdir3->Add(pfile6);pdir1->Add(pdir4);pdir4->Add(pfile7);pdir4->Add(pfile8);pdir1->ShowName(0);cout << "number of files: " << pdir1->countNumOfFiles() << endl;#endif#if 1using namespace ns4;shared_ptr<Employee> clerk1(new Employee("Laura", "Marketing", 10000));shared_ptr<Employee> clerk2(new Employee("Bob", "Marketing", 10000));shared_ptr<Employee> headMarketing(new Employee("Michel", "Head Marketing", 20000));headMarketing->add(clerk1);headMarketing->add(clerk2);shared_ptr<Employee> salesExecutive1(new Employee("Richard", "Sales", 10000));shared_ptr<Employee> salesExecutive2(new Employee("Rob", "Sales", 10000));shared_ptr<Employee> headSales(new Employee("Robert", "Head Sales", 20000));headSales->add(salesExecutive1);headSales->add(salesExecutive2);shared_ptr<Employee> CEO(new Employee("John", "CEO", 30000));CEO->add(headSales);CEO->add(headMarketing);cout << CEO->toString() << endl;cout << "------------------------------------------------------------" << endl;for (const shared_ptr<Employee> &e : CEO->getSubordinates()){cout << e->toString() << endl;for (const shared_ptr<Employee> &ee : e->getSubordinates())cout << ee->toString() << endl;}#endifcout << "Over!\n";return 0;}