树形结构在软件中随处可见,比如操作系统中的目录结构,公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题。组合模式通过一种巧妙的设计方案来使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致地处理树形结构中的叶子节点(不包含子节点的节点)和容器节点(包含子节点的节点).

一 组合模式简介

1.1 模式概述

组合(Composite)模式:组合多个对象形成树形结构以表示具有“整体-部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“部分-整体”(Part-Whole)模式,它是一种对象结构型模式。  

1.2 需求介绍

M公司开发部想要开发一个杀毒软件,该软件既可以针对某个文件夹杀毒,也可以针对某个指定的文件进行杀毒。该杀毒软件还可以根据各类文件的特点,为不同类型的文件提供不同的杀毒方式,例如图像文件(ImageFile)和文本文件(TextFile)的杀毒方式就有所差异。现需要提供该杀毒软件的整体框架设计方案。

二 杀毒软件框架设计

  首先在D盘创建如下树结构:

  

2.1 类图

  

2.2 代码实现

2.2.1 抽象文件类

#pragma once

#include <vector>
#include <map> #include <iostream>
using namespace std; // 抽象文件管理类
class CAbsFile
{
public:
CAbsFile(){}
virtual ~CAbsFile(){} virtual void AddFile(CAbsFile *pFile)
{
m_FileVect.push_back(pFile);
} virtual void RemoveFile(string strFileName)
{
vector<CAbsFile*>::iterator iter;
for (iter= m_FileVect.begin(); iter != m_FileVect.end(); iter ++)
{
if ( == strFileName.compare((*iter)->m_strFileName))
{
m_FileVect.erase(iter);
}
}
} virtual CAbsFile* GetChild(string strFileName)
{
vector<CAbsFile*>::iterator iter;
for (iter= m_FileVect.begin(); iter != m_FileVect.end(); iter ++)
{
if ( == strFileName.compare((*iter)->m_strFileName))
{
return *iter;
}
} return NULL;
} virtual void PrintFileStruct()
{
cout << m_strFileName.c_str() <<endl;
vector<CAbsFile*>::iterator iter;
for (iter= m_FileVect.begin(); iter != m_FileVect.end(); iter ++)
{
CAbsFile *pFile = *iter;
pFile->PrintFileStruct();
}
} virtual void DeleteObject()
{
vector<CAbsFile*>::iterator iter;
for (iter= m_FileVect.begin(); iter != m_FileVect.end(); iter ++)
{
CAbsFile *pFile = *iter;
pFile->DeleteObject();
} delete this;
}
virtual void KillVirus() = ; public:
vector<CAbsFile*> m_FileVect;
string m_strFileName;
};

2.2.2 具体text文件类

class CTextFile : public CAbsFile
{
public:
CTextFile(string strFileName)
{
m_strFileName = strFileName;
cout << "CTextFile Construct" << endl;
} ~CTextFile()
{
cout << "CTextFile Deconstruct" << endl;
} void KillVirus()
{
cout << "对文本文件:" << m_strFileName.c_str() << "进行杀毒操作" << endl;
}
};

2.2.3 具体img文件类

class CImgFile : public CAbsFile
{
public:
CImgFile(string strFileName)
{
m_strFileName = strFileName;
cout << "CImgFile Construct" << endl;
} ~CImgFile()
{
cout << "CImgFile Deconstruct" << endl;
} void KillVirus()
{
cout << "对图像文件:" << m_strFileName.c_str() << "进行杀毒操作" << endl;
}
};

2.2.4 具体文件夹类

class CFolder : public CAbsFile
{
public:
CFolder(string strFileName)
{
m_strFileName = strFileName;
cout << "CFolder Construct" << endl;
} ~CFolder()
{
cout << "CFolder Deconstruct" << endl;
} void KillVirus()
{
cout << "对文件夹:" << m_strFileName.c_str() << "进行杀毒操作" << endl;
vector<CAbsFile*>::iterator iter;
for (iter= m_FileVect.begin(); iter != m_FileVect.end(); iter ++)
{
CAbsFile *pFile = *iter;
pFile->KillVirus();
}
}
};

2.3 代码测试

#include "stdio.h"

#include "compose.h"

void main()
{
// 创建文件对象
cout << "创建文件对象" << endl;
CAbsFile *pFolderD = new CFolder("本地磁盘D");
CAbsFile *pFolderComposeTest = new CFolder("ComposeTest");
CAbsFile *pFolderImgFiles = new CFolder("ImgFiles");
CAbsFile *pFolderTextFiles = new CFolder("TextFiles");
CAbsFile *pImgFile = new CImgFile("Image.png");
CAbsFile *pTextFile = new CTextFile("1.txt"); // 构建文件组合
pFolderImgFiles->AddFile(pImgFile);
pFolderTextFiles->AddFile(pTextFile);
pFolderComposeTest->AddFile(pFolderImgFiles);
pFolderComposeTest->AddFile(pFolderTextFiles);
pFolderD->AddFile(pFolderComposeTest);
// 打印文件夹结构
cout << "打印本地磁盘D文件结构" << endl;
pFolderD->PrintFileStruct();
cout <<endl;
// 对composeTest文件夹进程杀毒操作
cout << "对composeTest文件夹进程杀毒操作" << endl;
pFolderComposeTest->KillVirus();
cout << endl; // 对单个img文件进行杀毒操作
cout << "对单个img文件进行杀毒操作" << endl;
pImgFile->KillVirus();
cout <<endl; cout << "释放文件对象" << endl;
pFolderD->DeleteObject();
return;
}

  在具体实现时,可以创建图形界面让用户自己选择所需操作的根节点,无需修改源代码,符合开闭原则,客户端无须关心节点的层次结构,可以对所选节点进行统一处理,提高系统的灵活性。

三 组合模式小结

3.1 主要优点

  (1)可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使客户忽略了层次的差异,方便对整个层次结构进行控制。

  (2)增加新的容器构件和叶子构件都十分方便,无需对现有类库代码进行任何修改,符合开闭原则

  (3)为树形结构的面向对象实现提供了灵活地解决方案,可以形成复杂的树形结构,但对树形结构的控制却很简单

3.2 主要缺点

  增加新构件时很难对容器中的构建类型进行限制。

3.3 适用场景

  (1)在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待他们。

  (2)在一个使用面向对象语言开发的系统中需要处理一个树形结构。

设计模式之组合(compose)模式的更多相关文章

  1. C++设计模式实现--组合(Composite)模式

    一. 举例 这个样例是书上的,如果有一个公司的组结结构例如以下: 它的结构非常像一棵树,当中人力资源部和財务部是没有子结点的,详细公司才有子结点. 并且最关健的是,它的每一层结构非常相似. 代码实现例 ...

  2. Head First 设计模式 —— 11. 组合 (Composite) 模式

    思考题 我们不仅仅要支持多个菜单,升值还要支持菜单中的菜单.你如何处理这个新的设计需求? P355 [提示]在我们的新设计中,真正需要以下三点: P354 我们需要某种属性结构,可以容纳菜单.子菜单和 ...

  3. C#设计模式(10)——组合模式(Composite Pattern)

    一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...

  4. c++设计模式15 --组合模式

    今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...

  5. 乐在其中设计模式(C#) - 组合模式(Composite Pattern)

    原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...

  6. php设计模式七 ---组合模式

    1.介绍 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结 ...

  7. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  8. Java进阶篇设计模式之六 ----- 组合模式和过滤器模式

    前言 在上一篇中我们学习了结构型模式的外观模式和装饰器模式.本篇则来学习下组合模式和过滤器模式. 组合模式 简介 组合模式是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来 ...

  9. 设计模式のCompositePattern(组合模式)----结构模式

    一.产生背景 又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 这种模 ...

  10. C#设计模式(10)——组合模式(Composite Pattern)(转)

    一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...

随机推荐

  1. mysql的常用语句

    Mysql的常用语句 -- 创建表 create table tableName( id int primary key, name varchar(20) ) -- 查询 select * from ...

  2. 使用AutoIT检测已安装软件,并将结果保存在桌面

    $file = "\adobe安装列表.txt" $regedit1 = "hklm64\SOFTWARE\Wow6432Node\Microsoft\Windows\C ...

  3. Spring MVC执行原理和基于Java的配置过程

    一.Spring MVC执行原理和基于Java配置的配置过程 (一)Spring MVC执行过程,大致为7步. 所有的请求都会经过Spring的一个单例的DispacherServlet. Dispa ...

  4. Maven的简介

    1 What? 1.1 Maven 简介Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和依赖管理.Maven 这个单词的本意是:专家,内行. ...

  5. SFTP无法连接 Connection closed by server with exitcode 127

    命令: Pass: ************状态: Connected to 66.77.88.99错误: Connection closed by server with exitcode 127错 ...

  6. LeetCode——Find All Numbers Disappeared in an Array

    LeetCode--Find All Numbers Disappeared in an Array Question Given an array of integers where 1 ≤ a[i ...

  7. Makefile文件应用——complicated项目

    学习资料 本文主要参考资料:驾驭Makefile(李云).pdf Complicated项目 需求: (1)object文件放到objs目录下 (2)可执行文件放到exes目录下 (3)增加头文件依赖 ...

  8. jsp基础知识点——思维导图

    如图 思维导图图片链接 http://www.edrawsoft.cn/viewer/public/s/0b8cd083478732 有道云笔记图片链接 http://note.youdao.com/ ...

  9. java+opencv+intellij idea实现人脸识别

    首先当然是需要安装opencv了,我用的是opencv2.4.13.下载完之后就可以直接安装了,安装过程也很简单,直接下一步下一步就好,我就不上图了. 接下来在opencv下找到jar包,比如我直接安 ...

  10. MySQL 触发器简单实例 - 转载

    MySQL 触发器简单实例 触发器:可以更新,删除,插入触发器,不同种类的触发器可以存在于同一个表,但同种类的不能有多个.一个更新.一个删除是可以共存的. ~~语法~~ CREATE TRIGGER  ...