组合模式 Composite[通俗易懂]

组合模式 Composite[通俗易懂]组合模式 Composite动机模式定义实例结构要点总结笔记动机在软件某些情况下,客户代码过多地依赖于对象容器复杂的内部实现结构,对象内部实现结构(而非抽象接口)地变化将引起客户代码地频繁变化.带来代码地维护性,扩展性等弊端如何将”客户代码与复杂地对象容器结构”解耦?让对象容器自己来实现自身地复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂地对象容器模式定义将对象组合成树形结构以表示”整体-部分”地层次结构.Composite使得用户对单个对象和组合对象地使用具有一致性(稳定)实例树形


Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

动机

在软件某些情况下,客户代码过多地依赖于对象容器复杂的内部实现结构,对象内部实现结构(而非抽象接口)地变化将引起客户代码地频繁变化.带来代码地维护性,扩展性等弊端

如何将”客户代码与复杂地对象容器结构”解耦?让对象容器自己来实现自身地复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂地对象容器

模式定义

将对象组合成树形结构以表示”整体-部分”地层次结构.Composite使得用户对单个对象和组合对象地使用具有一致性(稳定)

实例

树形访问

#include<algorithm>
using namespace std;

class Component{ 
   
public:
    virtual void process() = 0;
    virtual ~Component(){ 
   }
}

class Composite : public Component{ 
   
    string name;
    List<Component *> elements;
public:
    Composite(const string &s) : name(s){ 
   }
    void add(Component *element){ 
   
        elements.push_back(element);
    }
    void remove(Component* element){ 
   
        elements.remove(element);
    }
    void process(){ 
   
        //process current node

        //process current nodes
        for (auto &e : elements){ 
   
            e->process();
        }
    }
}
class leaf : public Component{ 
   
    string name;
public:
    Leaf(string s) : name(s){ 
   }
    void process(){ 
   
        //process current node
    }
}

void Invoke(Component &c){ 
   
    //...
    c.process();
    //...
}

int main(){ 
   
    Composite root("root");
    Composite treeNode1("treeNode1");
    Composite treeNode1("treeNode2");
    Composite treeNode1("treeNode3");
    Composite treeNode1("treeNode4");
    Leaf left1("leaf1");
    Leaf left2("leaf2");

    root.add(&treeNode1);
    treeNode1.add(&treeNode2);
    treeNode2.add(&leaf1);

    root.add(&treeNode3);   //具有一致性
    treeNode3.add(&treeNode4);//具有一致性
    treeNode4.add(&left2);//具有一致性

    process(root);
}

int main(){ 
   

    return 0;
}

结构

在这里插入图片描述

要点总结

  • Composite 模式采用树形结构来实现普遍存在地对象容器,从而将”一对多”地关系转化为”一对一”地关系,使得客户代码可以一致地(复用)处理对象和对象容器,无需关心处理地是单个地对象.还是组合地对象容器.
  • 将”客户代码与复杂地对象容器结构”解耦是Composite地核心思想,解耦之后.客户代码将与纯粹地抽象接口–而非对象容器地内容实现结构—发生依赖,从而更能”应对变化”
  • Compoiste模式在具体实现中,可以让父对象中地子对象反向追溯 如果父对象有频繁地遍历需求,可使用缓存技巧来改善效率

笔记

  • 一致性指的是对待整体和对待单个 是一样地
  • 访问地时候把树形结构地访问封装在了内部 而不是暴漏在外部
  • add 和 remove函数地放置位置有争议
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • springJPA 之 QueryDSL(一)

    springJPA 之 QueryDSL(一)引言不可否认的是JPA使用是非常方便的,极简化的配置,只需要使用注解,无需任何xml的配置文件,语义简单易懂,但是,以上的一切都建立在单表查询的前提下的,我们可以使用JPA默认提供的方法,

    2022年8月4日
  • 2021【软件测试】面试题合集大放送「建议收藏」

    又到了金九银十跳槽求职旺季。准备好一场面试不仅需要在简历上多下功夫,还需要为面试问答做好充足的准备,简历书写请参考:https://blog.csdn.net/leboxy/article/details/100658701。以下是“大佬”本人从乐搏学院VIP学员面试经验中收集的,然后分门别类整理了这套面试题,很具备参考性,毕竟都是企业真实面试题目。接下来,针对以下知识类型列出具体的面试点(其中…

    2022年4月10日
  • MacBook安装Windows_macbookpro安装双系统

    MacBook安装Windows_macbookpro安装双系统MacBook安装Redis官方下载地址:https://redis.io/download官方提供安装的相关命令了#下载redis包wgethttp://download.redis.io/releases/redis-4.0.10.tar.gz#解压tar-zxvfredis-4.0.10.tar.gz#进入目录cdredis-4.0.10#编译make#启动redis服务src/redis-server#启动redis客户端连接src/redis-cli

    2022年10月23日
  • ZPL指令_TSC指令

    ZPL指令_TSC指令^CC,~CC改变格式指令前缀  ^CC,~CC(改变脱字符)指令是用于改变指令前缀。缺省前缀是脱字符(^)。^CC,~CC指令格式  ^CCx,~CCx^CC,~CC=改变脱字符x=任何ASCII字符  缺省值:要求有参数。如不用参数,下一字符接收后作为新的前缀字符。

    2022年10月25日
  • pmos开关电路原理_高频开关电源电路图

    pmos开关电路原理_高频开关电源电路图​概述负载开关电路日常应用比较广泛,主要用来控制后级负载的电源开关。此功能可以直接用IC也可以用分立器件搭建,分立器件主要用PMOS加三极管实现。本文主要讨论分立器件的实现的细节。电路分析如下图所示R5模拟后级负载,Q1为开关,当R3端口的激励源为高电平时,Q2饱和导通,MOS管Q1的VGS<VGSth导通,R5负载上电,关断时负载下电。电路中R3为三极管Q2的限流电阻,R4为偏置电阻,R1R2为Q1的栅极分压电阻,C1C2为输出滤波电容。提出问题…

    2022年9月20日
  • Vue2.0的三种常用传值方式、父传子、子传父、非父子组件传值

    Vue2.0的三种常用传值方式、父传子、子传父、非父子组件传值Vue2.0传值方式:在Vue的框架开发的项目过程中,经常会用到组件来管理不同的功能,有一些公共的组件会被提取出来。这时必然会产生一些疑问和需求?比如一个组件调用另一个组件作为自己的子组件,那么我们如何进行给子组件进行传值呢?如果是电商网站系统的开发,还会涉及到购物车的选项,这时候就会涉及到非父子组件传值的情况。当然你也可以用Vuex状态管理工具来实现,这部分我们后续会单独介绍。先给大家介绍Vue常见的三种传值方式

    2022年5月13日

发表回复

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

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