组合模式的思考
①组合模式的本质:统一叶子对象和组合对象。它把叶子对象和组合对象都当成Component对象,有机地统一了叶子对象和组合对象。
②组合模式的目的:让客户端不用区分操作的是组合对象还是叶子对象,而是以统一的方式来操作。
③组合模式中存在天然的递归,这里所说的递归不是常说的“方法调用自己”的递归。而是指对象的递归组合。
Windows资源管理器
//声明文件
//结构型模式:组合模式
//场景:Windows资源管理
#include <iostream>
#include <string>
#include <list>
using namespace std;
//************************抽象组件类******************
class CAbsFile{
protected:
string strAttr; /*文件或目录名*/
public:
CAbsFile(string attr);
virtual ~CAbsFile();
//显示文件名或目录名
virtual void DispInfo();
//判断是文件还是目录
virtual bool IsFolder() = 0;
//添加子目录或文件
virtual bool Add(CAbsFile* file) = 0;
//删除子目录或文件
virtual bool Sub(CAbsFile* file) = 0;
//获得子节点
virtual list<CAbsFile*>* GetChildren() = 0;
};
//***********************具体组件角色*******************
class CFile : public CAbsFile{
public:
CFile(string attr);
~CFile();
bool IsFolder();
//添加子目录或文件 对于文件(叶子节点),无子结点
bool Add(CAbsFile* file);
//删除子目录或文件
bool Sub(CAbsFile* file);
//获得子节点
list<CAbsFile*>* GetChildren();
};
//*****************************组合组件对象**********************
class CFolder : public CAbsFile{
private:
list<CAbsFile*> lstFile;
public:
CFolder(string attr);
~CFolder();
bool IsFolder();
bool Add(CAbsFile* file);
bool Sub(CAbsFile* file);
list<CAbsFile*>* GetChildren();
};
void DispTree(CAbsFile* pRoot, int iDeep = 0);
void DelTree(CAbsFile* pRoot);
//实现文件
//************************抽象组件类******************
CAbsFile::CAbsFile(string attr){strAttr = attr;}
CAbsFile::~CAbsFile(){}
void CAbsFile::DispInfo(){cout << strAttr << endl;}
//***********************具体组件角色*******************
CFile::CFile(string attr) : CAbsFile(attr){}
CFile::~CFile(){ cout << strAttr << endl;}
bool CFile::IsFolder(){return false;}
//添加子目录或文件 对于文件(叶子节点),无子结点
bool CFile::Add(CAbsFile* file){return false;}
//删除子目录或文件
bool CFile::Sub(CAbsFile* file){return false;}
//获得子节点
list<CAbsFile*>* CFile::GetChildren(){return NULL;}
//*****************************组合组件对象**********************
CFolder::CFolder(string attr) : CAbsFile(attr){}
CFolder::~CFolder(){
cout << strAttr << endl;
for(list<CAbsFile*>::iterator it = lstFile.begin(); it != lstFile.end(); it++){
CAbsFile* pFile = (*it); delete pFile;
}
}
bool CFolder::IsFolder(){return true;}
bool CFolder::Add(CAbsFile* file){lstFile.push_back(file); return true;}
bool CFolder::Sub(CAbsFile* file){lstFile.remove(file); return true;}
list<CAbsFile*>* CFolder::GetChildren(){return &lstFile;}
void DispTree(CAbsFile* pRoot, int iDeep)
{
for(int i = 0; i < iDeep; i++){
cout << "--";
}
pRoot->DispInfo();//显示自身名称
list<CAbsFile*>* pLstFile = pRoot->GetChildren();
if(pLstFile != NULL){//获取子目录
for(list<CAbsFile*>::iterator it = pLstFile->begin(); it != pLstFile->end(); it++){
if((*it)->IsFolder()) DispTree(*it, iDeep+1);
else{
for(int i = 0; i < iDeep; i++) cout << "--";
(*it)->DispInfo();
}
}
}
}
void DelTree(CAbsFile* pRoot){
if(pRoot == NULL) return;
if(pRoot->GetChildren() != NULL){
for(list<CAbsFile*>::iterator it = pRoot->GetChildren()->begin(); it != pRoot->GetChildren()->end();){
CAbsFile* pFile = (*it);
if(pFile->IsFolder()) DelTree(pFile);
else delete pFile;
it = pRoot->GetChildren()->erase(it);
}
}
delete pRoot;
}
//测试客户端
void main()
{
CAbsFile* pRoot = new CFolder("C:\\");
CAbsFile* pFolder1 = new CFolder("ProgramFiles");
CAbsFile* pFolder2 = new CFolder("Windows");
CAbsFile* pCpp = new CFile("Test.cpp");
CAbsFile* pExe = new CFile("Test.exe");
//组织成树状结构
pRoot->Add(pFolder1);
pRoot->Add(pExe);
pFolder1->Add(pFolder2);
pFolder2->Add(pCpp);
//显示根目录及其子目录(或文件)
DispTree(pRoot);
cout << "**********************************************" << endl;
//DelTree(pRoot);
delete pRoot;
}