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

一 组合模式简介

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. sql中null 和 ‘’(空字符串)

    sql 中 null  和 空字符串的区别方式 在Silverlight中  数据库 需要与实体类进行映射, 假如实体类不允许为null,则 select '' as 列名  from  表名字:   ...

  2. 外部类与main方法笔记

    外部类 1. 外部public class只能有一个 2. 外部类只能有两种访问控制级别: public 和默认 3. 一个文件中,可以有多个public class,即外部类为public,还可以有 ...

  3. phoenix部署手册-基于hbase

    背景描述: phoenix基于hbase的SQL层,映射hbase的表,也可以映射视图(VIEW) 部署安装比较简单 映射表和视图的区别: 映射表: 在Phoenix建表错误不易更改: 删除会连同hb ...

  4. 20165101刘天野 2018-2019-2《网络对抗技术》Exp4 恶意代码分析

    20165101刘天野 2018-2019-2<网络对抗技术>Exp4 恶意代码分析 1. 实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2是分析一个恶意软件 ...

  5. COS-7设备管理

    操作系统(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在“裸机”上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行.   操作系 ...

  6. 解决org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z

    这个问题来的有点莫名奇妙,之前我的hadoop运行一直是正常的,某一天开始运行Mapreduce就报这个错. 试过很多种方法都没有用,比如 1.path环境变量2.Hadoop bin目录下hadoo ...

  7. RQN 273 马棚问题 dp

    PID273 / 马棚问题  2016-07-29 18:21:55 运行耗时:1624 ms 运行内存:16248 KB 题目描述 每天,小明和他的马外出,然后他们一边跑一边玩耍.当他们结束的时候, ...

  8. selenium学习笔记(HTMLTestRunner测试报告)

    之前提到selenium加入unittest框架.可以引入HTMLTestRunner扩展.以此来生成测试报告 首先是分享下载的百度云地址 http://pan.baidu.com/s/1pKUItW ...

  9. memcache笔记

    服务端: 通过printf配合nc向memcached中写入数据[root@yz6245 ~]# printf "set key1 0 0 6\r\noldboy\r\n" |nc ...

  10. 连接mysql报错:error 2003 (hy000):can't connect to mysql server on 'localhost' (10061)

    一.mysql 的bin目录下有个MySQLInstanceConfig.exe,运行就可以进行创建数据库实例,创建实例时也可以生成windows 服务,把服务设置成自动启动就可以了 二.安装在D盘的 ...