首页 > 系统相关 >Linux C++ 065-设计模式之组合模式

Linux C++ 065-设计模式之组合模式

时间:2024-07-20 22:28:07浏览次数:14  
标签:065 name 对象 Component iter add C++ Leaf 设计模式

Linux C++ 065-设计模式之组合模式

本节关键字:Linux、C++、设计模式、组合模式
相关库函数:

概念

组合模式(Composite Pattern),又叫做部分-整体模式,使得用户对单个对象和组合对象的使用具有一致性。它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。

角色说明

Component 是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

Leaf 在组合中表示叶子结点对象,叶子结点没有子结点。

Composite 定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

代码示例

// 将对象组合成树形结构以表示“部分——整体”的结构层次,使得客户端对单个对象或者组合对象的使用具有一致性。(在word复制一个字、一行文字、一段文字都是一样的操作)
// 把组合模式想象成一棵大树,大树分为树枝和树叶两部分,树枝可以长树枝和树叶,但是树叶不能再张别的东西。
// 
// 组合模式的适用情况:
//        希望表示对象的“部分——整体”的结构层次
//        希望客户端忽略单个对象和组合对象的不同,客户端统一处理的是组合对象
//
class Component
{
public:
    string name;
    Component(string name) {
        this->name = name;
    }
    virtual void add(Component*) = 0;
    virtual void remove(Component*) = 0;
    virtual void display(int) = 0;
};
// 叶子节点类,叶节点没有子节点
class Leaf : public Component
{
public:
    Leaf(string name) : Component(name) {}
    void add(Component* c) {
        cout << "leaf cannot add" << endl;
    }
    void remove(Component* c) {
        cout << "leaf cannot remove" << endl;
    }
    void display(int depth) {
        string str(depth, '-');
        str += name;
        cout << str << endl;
    }
};
// 枝节点类
class Composite : public Component
{
private:
    vector<Component*> component;
public:
    Composite(string name) : Component(name) { }
    void add(Component* c) {
        component.push_back(c);
    }
    void remove(Component* c) {
        vector<Component*>::iterator iter = component.begin();
        while (iter != component.end()) {
            if (*iter == c) {
                component.erase(iter);    // 当删除iter所指向的元素后,iter指向原删除元素的下一个位置,如果删除的是最后一个元素,iter指向末尾component.end()
                return;                    // 为了防止删除的是最后一个位置,再执行iter++时出错,我们在这里删除元素后直接返回
            }
            iter++;
        }
    }
    void display(int depth) {
        string str(depth, '-');
        str += name;
        cout << str << endl;

        vector<Component*>::iterator iter = component.begin();
        while (iter != component.end()) {
            (*iter)->display(depth + 2);
            iter++;
        }
    }
};
int main_Component()
{
    Component* p = new Composite("LI");
    Leaf* l = new Leaf("WANG");
    
    // 增加树叶
    p->add(l);
    p->add(new Leaf("QIANG"));

    Component* sub = new Composite("HU");
    sub->add(new Leaf("WANG"));
    sub->add(new Leaf("MING"));
    sub->add(new Leaf("LIU"));

    // 增加树枝
    p->add(sub);
    p->display(0);
    
    cout << "****************" << endl;
    sub->display(2);
    cout << "****************" << endl;
    
    // 删除树枝
    p->remove(sub);
    p->display(0);
    return 0;
}
/* 运行结果:
LI
--WANG
--QIANG
--HU
----WANG
----MING
----LIU
*******
--HU
----WANG
----MING
----LIU
*******
LI
--QIANG
--HU
----WANG
----MING
----LIU
*******
LI
--QIANG
*/
// 组合模式完美的使用了面向对象里面的多态性,叶子类和树枝类都继承了一个抽象基类(Component)
// 叶子类:只能进行显示
// 树枝类:可以增加、删除、显示叶子或者树枝对象,传入的参数都是抽象基类的指针, 因为可以在运行的过程中进行动态绑定,来决定是操作叶子对象还是操作树枝对象
// 客户端:实例化抽象基类的对象指针,该指针指向树枝类的对象;可以通过该指针访问树枝类的对象,对其进行增加叶子对象或者数值对象,删除叶子对象或者数值对象
//

标签:065,name,对象,Component,iter,add,C++,Leaf,设计模式
From: https://blog.csdn.net/qq_45157350/article/details/135869924

相关文章

  • Linux C++ 066-设计模式之访问者模式
    LinuxC++066-设计模式之访问者模式本节关键字:Linux、C++、设计模式、访问者模式相关库函数:概念在访问者模式(VisitorPattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模......
  • C++面向对象编程的一个核心概念--RAII
    RAII是"ResourceAcquisitionIsInitialization"(资源获取即初始化)的缩写,它是C++编程中的一种编程技术,用于管理资源的生命周期。RAII是C++面向对象编程的一个核心概念,它利用对象的构造函数和析构函数来自动管理资源,如内存、文件句柄、线程、互斥锁等。RAII的主要原则包括:1.*......
  • 如何使用C++中的字符串类(如std::string)
    在C++中,std::string 类是标准模板库(StandardTemplateLibrary,STL)的一部分,它提供了对字符串的灵活处理。std::string 使得字符串的存储、操作、比较、查找等任务变得更加方便和高效。下面将介绍如何使用 std::string 类。1.包含头文件要使用 std::string,首先需要包含......
  • 掌握 C++ 异常艺术:构建健壮程序的秘诀与实战策略「一」
    以下内容为本人的烂笔头,如需要转载,请全文无改动地复制粘贴,原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/WC8CThJ77oHMsCSH0CBzsQ在过去几十年的编程历史中,异常处理的演变仿佛一场文明的进化史,它不仅仅是技术的革新,更是编程思想与哲学的深刻体现。从古早的错......
  • Android C++系列:Linux文件系统(二)
    1.VFS虚拟文件系统Linux支持各种各样的文件系统格式,如ext2、ext3、reiserfs、FAT、NTFS、iso9660等等,不同的磁盘分区、光盘或其它存储设备都有不同的文件系统格式,然而这些文件系统都可以mount到某个目录下,使我们看到一个统一的目录树,各种文件系统上的目录和文件我们用l......
  • Android C++系列:函数返回值注意事项
    1.背景函数返回值就是使用return语句终止正在执行的函数,看是很简单的问题有什么说的呢?因为越是简单的问题里面越是有一些不易发现的坑。比如在循环中使用return语句:boolfindChar(conststring&str,constcharc){autosize=str.size();for(decltype(size......
  • Perl中的设计模式革新:命令模式的实现与应用
    Perl中的设计模式革新:命令模式的实现与应用在面向对象编程中,设计模式是解决特定问题的成熟模板。命令模式作为行为设计模式之一,它将请求封装为对象,从而允许用户根据不同的请求对客户进行参数化。本文将深入探讨如何在Perl中实现命令模式,并提供详细的代码示例,帮助开发者在Pe......
  • 【C++BFS 回溯】756. 金字塔转换矩阵
    本文涉及知识点C++BFS算法C++回溯LeetCode756.金字塔转换矩阵你正在把积木堆成金字塔。每个块都有一个颜色,用一个字母表示。每一行的块比它下面的行少一个块,并且居中。为了使金字塔美观,只有特定的三角形图案是允许的。一个三角形的图案由两个块和叠在上面的单......
  • GESP C++ 二级真题(2023年12月)T1 小杨做题
    问题描述:为了准备考试,小杨每天都要做题。第一天做了a道题;第二天做了b道题;从第三天起,小杨每天做的题目数量是前两天的总和。此外,小杨还规定当自己某一天做了大于或等于m题时,接下来的日子,他就不做题了。请问到了第n天,小杨总共做了多少道题?输入描述:总共4行。第一行一个整数a,......
  • 使用GDAL(C++库)从末尾行开始向上读取图像数据
    使用GDAL(C++库)从末尾行读取图像数据OpenCV等图像库默认的读取方式都是从第一行开始,逐行读取数据(自顶向下),填充到内存缓冲区;对于某些特殊应用,需要反行序读取(从末尾行读到起始行)的图像数据结果。GDAL提供了灵活的栅格数据读取方式RasterIO,下面介绍RasterIO的调用方式,以及如何......