设计模式之组合(compose)模式
树形结构在软件中随处可见,比如操作系统中的目录结构,公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题。组合模式通过一种巧妙的设计方案来使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致地处理树形结构中的叶子节点(不包含子节点的节点)和容器节点(包含子节点的节点).
一 组合模式简介
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)模式的更多相关文章
- C++设计模式实现--组合(Composite)模式
一. 举例 这个样例是书上的,如果有一个公司的组结结构例如以下: 它的结构非常像一棵树,当中人力资源部和財务部是没有子结点的,详细公司才有子结点. 并且最关健的是,它的每一层结构非常相似. 代码实现例 ...
- Head First 设计模式 —— 11. 组合 (Composite) 模式
思考题 我们不仅仅要支持多个菜单,升值还要支持菜单中的菜单.你如何处理这个新的设计需求? P355 [提示]在我们的新设计中,真正需要以下三点: P354 我们需要某种属性结构,可以容纳菜单.子菜单和 ...
- C#设计模式(10)——组合模式(Composite Pattern)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
- c++设计模式15 --组合模式
今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...
- 乐在其中设计模式(C#) - 组合模式(Composite Pattern)
原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...
- php设计模式七 ---组合模式
1.介绍 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结 ...
- JavaScript设计模式之----组合模式
javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...
- Java进阶篇设计模式之六 ----- 组合模式和过滤器模式
前言 在上一篇中我们学习了结构型模式的外观模式和装饰器模式.本篇则来学习下组合模式和过滤器模式. 组合模式 简介 组合模式是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来 ...
- 设计模式のCompositePattern(组合模式)----结构模式
一.产生背景 又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这种类型的设计模式属于结构型模式,它创建了对象组的树形结构. 这种模 ...
- C#设计模式(10)——组合模式(Composite Pattern)(转)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
随机推荐
- Spring Web MVC 随笔
1.ContextLoaderListener 对于使用Spring的Web应用,无需手动创建Spring容器,而是通过配置文件声明式地创建Spring容器.可以直接在web.xml文件中配置创建Sp ...
- javascript Date对象 之 获取时间
javascript Date对象 --> 获取时间: 测试代码: <!DOCTYPE html> <html lang="en"> <head ...
- com.android.tools.build:gradle:X.XX.XX:gradle.jar 插件无法下载问题
在使用Android Studio 这个IDE时,出现com.android.tools.build:gradle:X.XX.XX:gradle.jar 插件无法下载问题 可能的原因就是网速不好或者依 ...
- php编写的抽奖程序中奖概率算法
本文给大家分享的是php中奖概率算法,可用于刮刮卡,大转盘等抽奖算法.用法很简单,代码里有详细注释说明,一看就懂,有需要的小伙伴参考下吧. 我们先完成后台PHP的流程,PHP的主要工作是负责配置奖项及 ...
- LeetCode——Longest Consecutive Sequence
LeetCode--Longest Consecutive Sequence Question Given an unsorted array of integers, find the length ...
- CocoaPods学习系列5——错误集锦
这篇文章记录使用CocoaPods过程中遇到的一些错误. 1.error:include of non-modular header inside framework module 在自定义类库中,引 ...
- 转 : Java的版本特性与历史
Java Versions, Features and History This article gives you a highlight of important features added i ...
- scala学习手记16 – scala中的static
前面两节学了scala的对象和伴生对象,这两个在使用的时候很有些java的静态成员的意思. scala中没有静态字段和静态方法.静态成员会破坏scala所支持的完整的面向对象模型.不过可以通过伴生对象 ...
- python脚本3_输入若干个整数打印出最大值
#输入若干个整数,打印出最大值 # m = int(input('Input first number >>>')) while True: c = input('Input a n ...
- QQ钱包,微信,京东钱包,百度钱包,支付宝AGENT
微信Mozilla/5.0 (Linux; Android 7.0; LON-AL00 Build/HUAWEILON-AL00; wv) AppleWebKit/537.36 (KHTML, lik ...