• 二十三、设计模式之组合模式![



    在这里插入图片描述

    魔战已经完结。成功登顶。占领敌军最高峰。

    二十三、设计模式之组合模式

    “组合模式”也被称为“部分整体模式”该模式属于结构型模式的一种。
    将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

    所属类型定义
    结构型将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

    能帮我们干什么?

    主要解决什么问题?

    主要解决的是 它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

    优缺点

    优点

    1、高层模块调用简单。
    2、节点自由增加。

    缺点:

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


    使用的场景

    以下情况下适用Composite模式:
    1.你想表示对象的部分-整体层次结构
    2.你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
    部分、整体场景,如树形菜单,文件、文件夹的管理。

    理解

    讲解该模式之前先带大家熟悉一下“树形结构”。相信大家对“树形结构”不会太陌生,如果你刚好不太了解的话可以想一下大树,一颗树它分别有树根、树枝、树叶,正好树形结构中也有根节点、子节点(非叶子节点)、叶子节点。
    在这里插入图片描述

    组合模式就运用了树形结构,该模式的核心思想是:将多个对象组合成树形结构,以此结构来表示“整体-部分”之间的层次关系。

    实现

    在这里插入图片描述

    角色

    1. Component:组合模式中的“根节点”,可以是接口、抽象类、普通类,该类中定义了其子类的所有共性内容,并且该类中还存在着用于访问和管理它子部件的方法。
    2. Leaf:组合中的叶子节点,也就是最末端的节点,该节点下不会再有子节点。
    3. Composite:非叶子节点,它的作用是存储子部件,并且在Composite中实现了对子部件的相关操作。

    组合模式

    如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

    关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

    实现难度: ⭐️ ⭐️ ⭐️ ⭐️

    举例:
    java/com/kongxiang/raindrop/dp/type/structure/composite · master · 无难事者若执 / 23种设计模式 · GitCode
    叶节点和组合节点。

    component

    public abstract class Component {
      protected  String name;
      public Component(String name){
        this.name = name;
      }
    
      public abstract void draw();
    
      public abstract void add(Component component);
    
      public abstract void remove(Component component);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    leaf

    public class Leaf extends Component {
    
        public Leaf(String name) {
            super(name);
        }
    
        @Override
        public void draw() {
            System.out.println(this.name);
        }
    
        @Override
        public void add(Component component) {
            throw new IllegalArgumentException("叶节点不能添加组件");
        }
    
        @Override
        public void remove(Component component) {
            throw new IllegalArgumentException("叶节点不能移除组件");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    composite

    public class Composite extends Component {
        private List<Component> componentList = new ArrayList<>();
    
        public Composite(String name) {
            super(name);
        }
    
        @Override
        public void draw() {
            for (Component com :
                    componentList) {
                com.draw();
            }
        }
    
        @Override
        public void add(Component component) {
            this.componentList.add(component);
        }
    
        @Override
        public void remove(Component component) {
            this.componentList.remove(component);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    client

         public static void main(String[] args) {
            Leaf leaf = new Leaf("张三”");
            Leaf leaf1 = new Leaf("张4”");
            Leaf leaf2 = new Leaf("张5”");
            Leaf leaf3 = new Leaf("张6”");
            Leaf leaf4 = new Leaf("张7”");
    
            Composite composite = new Composite("组1");
            composite.add(leaf);
            composite.add(leaf1);
            Composite composite2 = new Composite("组2");
            composite2.add(leaf2);
            composite2.add(leaf3);
            Composite composite3 = new Composite("组3");
            composite3.add(leaf4);
    
            composite.add(composite2);
            composite2.add(composite3);
    
            composite.draw();
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    总结

    组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。
    如果你想要创建层次结构,并可以在其中以相同的方式对待所有元素,那么组合模式就是最理想的选择。本章使用了一个文件系统的例子来举例说明了组合模式的用途。在这个例子中,文件和目录都执行相同的接口,这是组合模式的关键。通过执行相同的接口,你就可以用相同的方式对待文件和目录,从而实现将文件或者目录储存为目录的子级元素。

  • 相关阅读:
    并发bug之源(一)-可见性
    Python 中 is 和 == 的区别
    题目 1924: 蓝桥杯-01背包
    神经网络全连接层的作用,各种神经网络的优缺点
    LiveQing视频点播流媒体RTMP推流服务功能-支持视频点播分屏大屏展示视频轮巡分组播放RMP推流直播大屏展示
    如何理解Quadratic Weighted Kappa?
    IonQ联合GE Research证实:量子计算在风险聚合上有巨大潜力
    数据化运营15 活跃(上):如何通过运营手法提升⽤户活跃度?
    【学习笔记54】运动函数的分析
    阿里云2核4G服务器支持多少人在线?多少钱?
  • 原文地址:https://blog.csdn.net/k316378085/article/details/133989478