组合模式
来源:互联网 发布:淘宝日本直邮物流信息 编辑:程序博客网 时间:2024/04/29 05:45
组合模式
- 组合模式
- 概念
- 角色及职责
- 案例
概念
组合模式,是(构造型)结构型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。
角色及职责
Component (树形结构的节点抽象)
- 为所有的对象定义统一的接口(公共属性,行为等的定义)
- 提供管理子节点对象的接口
- [可选]提供管理父节点对象的接口
Leaf (树形结构的叶节点)
Component的实现子类–普通文件Composite(树形结构的枝节点)
Component的实现子类–子目录
适用于:
单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分–整体”
案例
#include <iostream>#include <list>using namespace std;/**树形结构--共同接口--整体和部分* 文件夹--普通文件--文件夹(三个中任意两个或三个类型的组合)* 文件夹下又有文件夹和普通文件(典型的树形结构)*//*抽象类--子树或者叶子节点均继承自他*/class IFile{public: virtual void display()=0; virtual int add(IFile *file) = 0; virtual int remove(IFile* file) = 0; virtual list<IFile *> *getChild()=0; string getName() { return m_name; }public : string m_name;//子树(子文件夹)或者叶子节点(普通文件)的名字 int cnt;//记录当前对象的下一级对象(目录或文件)前面应该有的分隔符("--")数量 //--表示第几层子目录 //分隔符("--")数量表示当前目录相对根目录来说是第几层子目录};/*叶子节点--普通文件*/class File : public IFile{public: File(string name)//构造函数 { m_name = name; cnt = 0; } virtual void display()//普通文件的显示函数--直接显示名字 { cout<<m_name<<endl; } /*不具备插入孩子属性--返回-1*/ virtual int add(IFile *file) { return -1; } /*不具备删除孩子属性--返回-1*/ virtual int remove(IFile* file) { return -1; } /*不具备获取孩子属性--返回-1*/ virtual list<IFile *>*getChild() { return NULL; }};/*子树部分--目录将目录和普通文件组合--组合模式构成文件系统的树形图*/class Dir : public IFile{private: list<IFile*> * m_list;public: Dir(string name) { m_name = name; m_list = new list<IFile *>;//为孩子起始位置分配空间--建立一个链表 m_list->clear();//链表清空 cnt = 0;//表示当前目录就是根目录--根目录的0级子目录 } /*对于目录的显示函数--需要递归显示子目录*/ virtual void display() { /*1.获取当前目录孩子的起始位置--m_list*/ list<IFile*> *chil_list = getChild(); /*2.显示当前目录的名字*/ cout<<m_name<<endl; /*3.如果孩子非空表示该目录有子目录或者文件 *如果为空表示是空文件夹,什么也不做--退出显示函数不进行递归 * --递归结束的条件--孩子为空(空目录或者普通文件都会结束递归) */ if(chil_list != NULL && !chil_list->empty()) { this->cnt++;//3.1 当前目录有子目录或者文件--前面的分隔符数量加1 /*3.2 遍历当前目录的孩子--当前目录的文件或者子目录*/ for( list<IFile*>::iterator it = chil_list->begin();it != chil_list->end();it++) { for(int i = 0;i < this->cnt;i++)//3.3 根据cnt打印分隔符--层级越深,cnt越大-- //每一级目录的cnt表示他的下一级文件或者子目录相对于根目录(调用display函数的对象)的层级关系 cout<<"--"; (*it)->cnt = this->cnt;//3.4 将当前目录的cnt传承给下一级的文件或者子目录-- //--下一级文件或者目录前面的分隔符是在上一级的基础上递增的 (*it)->display();//3.5 递归显示每一个孩子节点 } } /*4. 在显示结束以后要将根目录(调用display函数的对象)的层级关系清零 --否则再次调用的时候会在上一次的基础上累加分隔符数量*/ cnt = 0; } /*向目录添加孩子--子目录或者文件*/ virtual int add(IFile *file) { m_list->push_back(file);//将孩子插入链表 return 0; } /*从目录删除孩子--从链表移除一个孩子节点*/ virtual int remove(IFile* file) { m_list->remove(file); return 0; } /*获取孩子的起始位置*/ virtual list<IFile *>*getChild() { return m_list; }};/*测试案例*/int main(){ Dir * root = new Dir("C");//根目录 root->display(); Dir * dir1 = new Dir("folder1");//子目录1 File * file1 = new File("a.txt");//文件1 root->add(dir1); root->add(file1); root->display(); Dir * dir2 = new Dir("folder2");//子目录2 File * file2 = new File("b.txt");//文件2 dir1->add(dir2);//子目录2添加到子目录1 dir2->add(file2);//文件2添加到子目录2 dir1->add(file2);//文件2添加到子目录1 root->add(file2);//文件2添加到根目录 root->display();//显示根目录的文件系统结构 return 0;}
0 0
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- Fragment全解析系列
- Excel规划求解求哪几个数字之和等于一个固定值
- Oracle行转列、列转行的Sql语句总结
- 工厂模式
- spring aop 自动创建代理BeanNameAutoProxyCreator详解
- 组合模式
- 安卓中获取应用程序版本号和版本名称的方法
- 463. Island Perimeter
- pass on to the entire
- 网络爬虫(一):抓取网页的含义和URL基本构成
- 轻松理解javascript继承
- 解析PHP的session过期设置
- apache commons-logging与log4j和JDK logger的关系
- MyBatis:Parameter 'xxx' not found. Available parameters are [1, 0, param1, param2]错误