组合模式(结构型)

news2024/11/21 2:35:34

目录

一、前言

二、透明组合模式

三、安全组合模式

四、总结


一、前言

        组合模式(Composite Pattern)是一种结构型设计模式,将对象组合成树形结构以表示“部分-整体”得层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

        组合模式由以下角色组成:

Component(抽象组件):

一般是接口或者抽象类,是叶子构件和容器构件对象声明接口,抽象出访问以及管理子构件的方法,可以看做是根节点

Leaf(叶子结点):

在组合中表示叶子节点对象,叶子节点没有子节点,也就没有子构件

Composite(复合节点):

复合节点可以包含子节点,子节点可以是叶子节点,也可以是其他复合节点。可以看做是树枝节点

        整个组合模式的结构图:

二、透明组合模式

        组合模式分为透明和安全两种方式,在透明方式中,抽象组件中会声明所有类中的方法,客户端无法区别树叶对象和树枝对象,对客户端是透明的。但在树叶节点中,本来没有添加、删除放大,但却要实现它,是没有意义的。

        比如公司组织建构,公司有总公司,总公司下有财务部门、技术部门等,还有分公司,分公司也有财务部门,技术部门等。如果按照传统方式,总公司的财务部门、技术部门等需要代码实现,分公司的财务部门、技术部门也需要代码实现,但现实中这些部门的职责差不多,分公司其实可以复用总公司的财务部门、技术部门类。

        根据组合模式,我们便有以下代码实现:

        抽象组件Component类,即根节点:

public abstract class Component {


    abstract void add(Component component);

    abstract void remove(Component component);

    abstract void display(int depth);

    abstract void operation();
}

        复合节点Composite类,即树枝节点:

public class Composite extends Component{

    private List<Component> children = new ArrayList<>();

    private String name;

    public Composite(String name) {
        this.name = name;
    }

    @Override
    void add(Component component) {
        children.add(component);
    }

    @Override
    void remove(Component component) {
        children.remove(component);
    }

    @Override
    void display(int depth) {
        System.out.println("深度:" + depth + " 名称:" + name);
        for (Component component : children) {
            component.display(depth + 1);
        }
    }

    @Override
    void operation() {
        for (Component component : children){
            component.operation();
        }
    }
}

        叶子节点财务部门LeafOne类:

public class LeafOne extends Component{

    private String name;
    public LeafOne(String name) {
        this.name = name;
    }

    @Override
    void add(Component component) {

    }

    @Override
    void remove(Component component) {

    }

    @Override
    void display(int depth) {
        System.out.println("深度:" + depth + " 名称:" + name);
    }

    @Override
    void operation() {
        System.out.println(name + "财务操作");
    }
}

        叶子节点财务部门LeafTwo类:

public class LeafTwo extends Component{
    private String name;
    public LeafTwo(String name) {
        this.name = name;
    }

    @Override
    void add(Component component) {

    }

    @Override
    void remove(Component component) {

    }

    @Override
    void display(int depth) {
        System.out.println("深度:" + depth + " 名称:" + name);
    }

    @Override
    void operation() {
        System.out.println(name + "技术操作");
    }
}

        客户端调用类:

public class Client {

    public static void main(String[] args) {

        Component component = new Composite("北京总公司");
        component.add(new LeafOne("北京总公司财务部门"));
        component.add(new LeafTwo("北京总公司技术部门"));


        Component component1 = new Composite("上海分公司");
        component1.add(new LeafOne("上海分公司财务部门"));
        component1.add(new LeafTwo("上海分公司技术部门"));
        component.add(component1);



        Component component2 = new Composite("深圳分公司");
        component2.add(new LeafOne("深圳分公司财务部门"));
        component2.add(new LeafTwo("深圳分公司技术部门"));
        component.add(component2);

        System.out.println("公司架构:");
        component.display(1);
        System.out.println("职能:");
        component.operation();

    }
}

        运行结果:

三、安全组合模式

        相较于透明方式的组合模式,安全方式主要在抽象组件中不包含添加、删除操作,客户端调用中区分复合节点和叶子节点。

        抽象组件Component类:

public abstract class Component {

    abstract void display(int depth);

    abstract void operation();
}

        复合节点Composite类:

public class Composite extends Component{
    private List<Component> children = new ArrayList<>();

    private String name;

    public Composite(String name) {
        this.name = name;
    }

    public void add(Component component) {
        children.add(component);
    }

    public void remove(Component component) {
        children.remove(component);
    }
    @Override
    void display(int depth) {
        System.out.println("深度:" + depth + " 名称:" + name);
        for (Component component : children) {
            component.display(depth + 1);
        }
    }

    @Override
    void operation() {
        for (Component component : children){
            component.operation();
        }
    }
}

        叶子节点财务部门LeafOne类:

public class LeafOne extends Component {

    private String name;
    public LeafOne(String name) {
        this.name = name;
    }

    @Override
    void display(int depth) {
        System.out.println("深度:" + depth + " 名称:" + name);
    }

    @Override
    void operation() {
        System.out.println(name + "财务操作");
    }
}

        叶子节点财务部门LeafTwo类:

public class LeafTwo extends Component{
    private String name;
    public LeafTwo(String name) {
        this.name = name;
    }

    @Override
    void display(int depth) {
        System.out.println("深度:" + depth + " 名称:" + name);
    }

    @Override
    void operation() {
        System.out.println(name + "技术操作");
    }
}

        客户端调用:

public class Client {
    public static void main(String[] args) {
        Composite composite = new Composite("北京总公司");
        composite.add(new LeafOne("北京总公司财务部门"));
        composite.add(new LeafTwo("北京总公司技术部门"));


        Composite composite1 = new Composite("上海分公司");
        composite1.add(new LeafOne("上海分公司财务部门"));
        composite1.add(new LeafTwo("上海分公司技术部门"));
        composite.add(composite1);



        Composite composite2 = new Composite("深圳分公司");
        composite2.add(new LeafOne("深圳分公司财务部门"));
        composite2.add(new LeafTwo("深圳分公司技术部门"));
        composite.add(composite2);

        System.out.println("公司架构:");
        composite.display(1);
        System.out.println("职能:");
        composite.operation();
    }
}

        运行结果:

四、总结

        优点与缺点

优点:

1、高层模块(客户端)调用简单。组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码

2、节点自由增加,更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”

缺点:

1、在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则

2、设计较复杂,客户端需要花更多时间理清类之间的层次关系

3、不容易限制容器中的构件

4、不容易用继承的方法来增加构件的新功能

        使用场景:

        当需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式。      

        Spring中IOC就使用到组合模式,通过将组件组合成树形结构,实现了对象的依赖关系管理和生命周期控制。比如Spring中的CompositeCacheManager,Spring用来管理多个CacheManager的复合类。

文件系统:

组合模式可以用来表示文件系统的层次结构,使得客户端可以以统一的方式操作文件和文件夹,例如创建、删除、移动等。

组织机构:

组合模式可以用于表示组织机构的层次结构,例如公司的组织结构可以以树形结构来表示,根节点表示公司,子节点表示部门,叶子节点表示员工。使用组合模式可以统一地管理公司的组织结构,例如添加、删除部门或员工,查找某个部门的员工等。

图形界面控件:

图形界面中的控件可以被看作是一个层次结构,例如窗口控件可以包含按钮控件和文本框控件,按钮控件又可以包含图片控件等。组合模式可以用来表示控件的层次结构,使得客户端可以以统一的方式操作控件,例如添加、删除、遍历等。

菜单和菜单项:

在图形界面中,菜单可以包含菜单项,菜单项可以是子菜单或者普通的操作项。组合模式可以用来表示菜单和菜单项的层次结构,使得客户端可以以统一的方式操作菜单和菜单项,例如添加、删除、遍历等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1661427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库调优-SQL语句优化

2. SQL语句优化 sql 复制代码 # 请问这两条SQL语句有什么区别呢&#xff1f;你来猜一猜那条SQL语句执行查询效果更好&#xff01; select id from sys_goods where goods_name华为 HUAWEI 麦芒7 魅海蓝 6G64G 全网通; ​ select id from sys_goods where goods_id14967325985…

(九)JSP教程——pageContext对象

pageContext对象是由JSP容器创建并初始化的&#xff0c;相当于当前页面的容器&#xff0c;它可以访问当前页面中的所有对象。它的主要作用是为JSP页面包装上下文&#xff0c;并用于管理属于JSP的特殊可见部分中已命名对象的访问。 一般情况下&#xff0c;使用该对象的应用并不多…

netty配置SSL、netty配置https(开发)

netty配置SSL、netty配置https&#xff08;开发&#xff09; 我们在开发下使用ssl&#xff0c;所用的证书将不被客户端信任。 转自&#xff1a;https://lingkang.top/archives/netty-pei-zhi-ssl 方案一 快速。使用netty提供的临时签发证书 private static SslContext sslC…

富士Apeos 2350 NDA复印机报062 360代码故障

故障描述&#xff1a; 富士Apeos 2350 NDA复印机新机器刚拆箱安装&#xff0c;开机正常&#xff0c;自检扫描头一卡一卡的往前动几下就不动了、扫描灯也不亮扫描头也不能正常复位&#xff1b;按机器的复印键直接报062 360代码&#xff1b; 解答&#xff1a; 此代码为扫描故障&a…

unreal engine4 创建动画蒙太奇

UE4系列文章目录 文章目录 UE4系列文章目录前言一、创建动画蒙太奇 前言 动画蒙太奇的官方解释&#xff1a;Animation Montages are animation assets that enable you to combine animations in a single asset and control playback using Blueprints.You can use Animation…

粤嵌—2024/4/26—跳跃游戏 ||

代码实现&#xff1a; 方法一&#xff1a;回溯 历史答案剪枝优化——超时 int *dis;void dfs(int k, int startindex, int *nums, int numsSize) {if (dis[startindex] < k) {return;}dis[startindex] k;for (int i 0; i < nums[startindex]; i) {if (startindex i &…

mac内存不足怎么清理?有哪些免费的软件工具?

当你的mac电脑使用一段时间之后&#xff0c;你可能就会发现&#xff0c;原本非常流畅的运行开始出现卡顿的现象&#xff0c;此时正是mac内存不足的外在表现。可mac内存不足怎么清理呢&#xff0c;别急&#xff0c;清理内存的方式方法有很多&#xff0c;小编将结合实际情况给大家…

【Web】2023浙江大学生省赛初赛 secObj 题解

目录 step 0 step 1 step 2 step 3 题目本身是不难&#xff0c;简单复健一下 step 0 pom依赖就是spring 反序列化入口在./admin/user/readObj 输入流做了黑名单的过滤&#xff0c;TemplatesImpl不能直接打 可以jackson打SignedObject二次反序列化绕过 具体原理看下面这…

选择定制温度快速温变试验箱,为您开启高效试验新时代

在现代工业生产中&#xff0c;温度快速温变试验是评估产品性能和可靠性的重要手段之一。然而&#xff0c;市面上有大多数企业在选择试验设备时常常面临着一些困惑&#xff0c;那就是温度快速温变试验箱定制的性能与需求不匹配、定制服务不足、售后服务不到位等等。针对这些问题…

98、技巧-颜色分类

思路 这道题的思路是什么&#xff0c;首先典型荷兰国旗问题&#xff1a; 该问题的关键在于我们要将所有的0放到数组的前部&#xff0c;所有的1放在中间&#xff0c;所有的2放在后部。这可以通过使用两个指针&#xff0c;一个指向数组开头的“0”的最后一个位置&#xff0c;另…

第十一篇:操作系统新纪元:智能融合、量子跃迁与虚拟现实的交响曲

操作系统新纪元&#xff1a;智能融合、量子跃迁与虚拟现实的交响曲 1 引言 在数字化的浪潮中&#xff0c;操作系统如同一位智慧的舵手&#xff0c;引领着信息技术的航船穿越波涛汹涌的海洋。随着人工智能、物联网、量子计算等前沿技术的蓬勃发展&#xff0c;操作系统正站在一个…

【智能优化算法】金豺狼优化算法(Golden jackal optimization,GJO)

金豺狼优化(Golden jackal optimization,GJO)是期刊“Expert Systems with Applications”&#xff08;中科院一区IF 8.3&#xff09;的2022年智能优化算法 01.引言 金豺狼优化(Golden jackal optimization,GJO)旨在为解决实际工程问题提供一种替代的优化方法。GJO的灵感来自金…

鸿蒙开发接口Ability框架:【@ohos.application.Want (Want)】

Want Want模块提供系统的基本通信组件的能力。 说明&#xff1a; 本模块首批接口从API version 8 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import Want from ohos.application.Want; 开发前请熟悉鸿蒙开发指导文档&#xff1…

dev c++调试录入数字后回车直接关闭

1、我的dev c版本是5.11 2、输入7后&#xff0c;回车就没有了&#xff0c;原因是1013,1.cpp未包含在项目中 3、新建项目&#xff0c;并将test_debug.cpp包含在项目内&#xff0c;就可以下断点调试了

C语言—深入理解指针(3)

1.字符指针变量 一般使用&#xff1a; 另一种使用方法&#xff1a; “hello world”是一个常量字符串&#xff0c;不能被修改。 上述代码是将字符串中的首字符‘h’赋值给指针pstr&#xff0c;用%s打印字符串的时候&#xff0c;只需要提供首字符的地址就行。&#xff08;如果…

PPT基础

5种ppt仅可读形式 Ⅰ 开始选项卡 1.【幻灯片】组中&#xff1a;新建幻灯片&#xff0c;从大纲中导入幻灯片&#xff1b;修改幻灯片的版式&#xff1b;节&#xff08;新增节&#xff0c;重命名节&#xff09;。 2.【字体】组中&#xff1a;设置字体&#xff0c;字体大小&…

腾讯云coding代码托管平台配置问题公钥拉取失败提示 Permission denied(publickey)

前言 最近在学校有个课设多人开发一个游戏&#xff0c;要团队协作&#xff0c;选用了腾讯云的coding作为代码管理仓库&#xff0c;但在配置的时候遇到了一些问题&#xff0c;相比于github&#xff0c;发现腾讯的coding更难用&#xff0c;&#xff0c;&#xff0c;这里记录一下…

华为 Huawei 交换机 配置 Dot1q 终结子接口实现同设备 VLAN 间通信示例

组网需求 企业的不同部门拥有相同的业务&#xff0c;如上网、 VoIP 等业务&#xff0c;且各个部门中的用户位于不同的网段。目前存在不同的部门中相同的业务所属的VLAN 不相同&#xff0c;现需要实现不同VLAN中的用户相互通信。 如 图 7-7 所示&#xff0c;部门 1 和部门 2 中…

VM虚拟机安装调试(步骤如下图)

VM虚拟机安装调试 随着一顿安装操作&#xff0c;还有enter键敲下&#xff0c;出现如下界面。

Android 11 输入系统之InputDispatcher和应用窗口建立联系

InputDispatcher把输入事件传给应用之前&#xff0c;需要和应用窗口建立联系&#xff0c;了解了这个过程&#xff0c;就清楚了APP进程和InputDispatcher线程也就是SystemServer进程之间是如何传输数据了 我们向窗口addView的时候&#xff0c;都会调用到ViewRootImpl的setView方…