设计模式之组合(compose)模式

树形结构在软件中随处可见,比如操作系统中的目录结构,公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题。组合模式通过一种巧妙的设计方案来使得用户可以一致性地处理整个树形

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

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

一 组合模式简介

1.1 模式概述

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

1.2 需求介绍

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

二 杀毒软件框架设计

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

  设计模式之组合(compose)模式

2.1 类图

  设计模式之组合(compose)模式

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 (0 == 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 (0 == 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() = 0;

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;
}

设计模式之组合(compose)模式

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

三 组合模式小结

3.1 主要优点

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

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

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

3.2 主要缺点

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

3.3 适用场景

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

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

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/120139.html原文链接:https://javaforall.net

(0)
上一篇 2021年12月28日 上午11:00
下一篇 2021年12月28日 下午12:00


相关推荐

  • JAVA设计模式之门面模式(外观模式)[通俗易懂]

    医院的例子  现代的软件系统都是比较复杂的,设计师处理复杂系统的一个常见方法便是将其“分而治之”,把一个系统划分为几个较小的子系统。如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号、门诊、划价、化验、收费、取药等。看病的病人要与这些部门打交道,就如同一个子系统的客户端与一个子系统的各个类打交道一样,不是一件容易的事情。  首先病人必须先挂号,然后门诊。如果医生要求化验,病人必

    2022年3月11日
    50
  • 一句话评论设计模式六大原则

    原则,故名思议则是本质的意思。所谓擒贼先擒王,研究设计模式自然要先了解设计原则,所有的模式都是在这些原则的基础之上发展起来的,有的是侧重一个,有的是多个都有所涉及。看完设计模式之后,我感觉到每个模式都

    2021年12月25日
    43
  • JavaScript 设计模式之组合模式

    JavaScript 设计模式之组合模式引我们知道地球和一些其他行星围绕着太阳旋转,也知道在一个原子中,有许多电子围绕着原子核旋转。我曾经想象,我们的太阳系也许是一个更大世界里的一个原子,地球只是围绕着太阳原子的一个电子。而我身上的每个原子又是一个星系,原子核就是这个星系中的恒星,电子是围绕着恒星旋转的行星。一个电子中也许还包含了另一个宇宙,虽然这个宇宙还不能被显微镜看到,但我相信它的存在。也许这个想法有些异想天开,但在程序设计中,…

    2022年7月12日
    19
  • 设计模式 – 出厂模式(factory pattern) 详细说明

    设计模式 – 出厂模式(factory pattern) 详细说明

    2022年1月13日
    52
  • 螃蟹学PHP设计模式之中介者模式

    螃蟹学PHP设计模式之中介者模式

    2021年8月30日
    61
  • JAVA设计模式之单例模式

    本文继续介绍23种设计模式系列之单例模式。概念:  java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、登记式单例。  单例模式有以下特点:  1、单例类只能有一个实例。  2、单例类必须自己创建自己的唯一实例。  3、单例类必须给所有其他对象提供这一实例。  单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例…

    2022年3月11日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号