组合模式.cpp
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <list>
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 0
using 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 0
using 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 0
using 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 1
using 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;
}
#endif
cout << "Over!\n";
return 0;
}