设计模式 组合模式(Composite Pattern)

组合模式简绍

组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示"部分-整体"的层次结构。组合模式使得客户端可以用一致的方式处理单个对象和组合对象。这样,可以在不知道对象具体类型的条件下操作对象集合。

组合模式主要包含三种角色:

  • Component(组件):声明一个接口,在适当情况下,此接口被叶节点和容器节点共享。
  • Leaf(叶节点):定义终端对象。
  • Composite(容器节点):定义具有子部件的那些部件的行为。存储子部件。 组合模式的应用场景

组合模式的优缺点

组合模式的优点
  • 一致性:客户端可以一致地处理单个对象和组合对象。
  • 灵活性:可以很容易地添加新的叶子节点或组合节点。
  • 透明性:客户端不需要知道对象的具体类型就可以操作对象。
组合模式的缺点
  • 复杂性:对于简单操作,组合模式可能会引入不必要的复杂性。
  • 额外开销:组合模式可能会导致额外的内存和 CPU 开销,尤其是在处理大量对象时

UML图

定义一个公共接口或抽象类,它声明了所有叶子节点和容器节点共有的操作。

java 复制代码
package CompositePatternModel;

public interface Component {

    void test();

    Component getChild(int i);

    public void operation();

    public void add(Component component);
}

实现 Component 接口中定义的操作,但不关心其他与子节点相关的操作。

java 复制代码
package CompositePatternModel;

import java.util.ArrayList;
import java.util.List;

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

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

    @Override
    public void test() {

    }

    @Override
    public Component getChild(int i) {
        return children.get(i);
    }

    @Override
    public void operation() {
        System.out.println("Composite " + name + " operation");
        for (Component c : children) {
            c.operation();
        }
    }

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


}

实现 Component 接口中定义的操作,并且实现与子节点相关的操作。客户端可以一致地对待单个对象和组合对象。

java 复制代码
package CompositePatternModel;

public class Pattern implements  Component{
    private String name;

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

    @Override
    public void test() {
        System.out.println("test");
    }

    @Override
    public Component getChild(int i) {
        System.out.println("getChild");
        return null;
    }

    @Override
    public void operation() {
        System.out.println("operation: d" + name);
    }

    @Override
    public void add(Component component) {
        System.out.println("sdf"+ component);
    }

}

客户端可以一致地对待单个对象和组合对象。

java 复制代码
package CompositePatternModel;

public class Main {
    public static void main(String[] args) {
        Pattern pattern = new Pattern("pattern1");
        Pattern pattern1 = new Pattern("pattern2");

        Composite composite = new Composite("Comp");
        composite.add(pattern);
        composite.add(pattern1);
        composite.operation();
    }
}
 
  1. 表示部分-整体层次结构

    当你需要表示一个具有层次结构的对象集合时,组合模式是非常有用的。这种结构通常包含多个层次,每个层次上的对象可以是一个独立的实体(叶节点),也可以是一个包含其他对象的容器(组合节点)。

    示例:

    • 文件系统中的目录和文件:目录可以包含其他目录和文件。
    • 组织结构图:部门可以包含其他部门或员工。
    • UI控件:一个复合控件可以包含其他控件(如面板包含按钮、文本框等)
  2. 透明地处理单个对象和组合对象

    当客户端代码需要以一致的方式处理单个对象和组合对象时,组合模式可以让客户端无需关心处理的是单个对象还是组合对象。

    示例:

    • 图形编辑器:图形可以是单独的线条、矩形等基本图形,也可以是由多个基本图形组成的复合图形。
    • 渲染引擎:渲染对象可以是单一的几何体,也可以是由多个几何体组成的复杂场景。
  3. 动态地增删对象

    当需要在运行时动态地添加或移除对象,并且这些对象可能是单个实体也可能是包含其他对象的容器时,组合模式可以很好地支持这种需求。

    示例:

    游戏中的场景管理:游戏场景可以包含单个游戏对象,也可以包含其他场景。

    UI 界面构建:一个窗口可以包含多个面板,每个面板又可以包含多个组件。

  4. 需要递归处理的对象集合

    当需要对一个层次结构进行递归处理时,组合模式可以简化递归逻辑。

    示例:

    • 企业组织结构的遍历:遍历整个公司的部门和员工。
    • 文件系统的遍历:递归地遍历目录和文件。
  5. 需要一致的接口

    当希望在不同类型的对象之间提供一致的接口时,组合模式可以确保所有的对象(无论是叶子还是组合节点)都遵循相同的接口定义。

示例:

操作系统中的文件和目录:文件和目录都需要支持读写、删除等操作。

网页中的 DOM 结构:DOM 节点可以是文本节点也可以是包含其他节点的元素节点。

组合模式提供了一种优雅的方式来组织和操作层次结构中的对象,使得客户端可以在不知道对象具体类型的情况下操作对象集合。这种模式在很多领域都有广泛的应用,特别是在需要表示层次关系的场景中。

相关推荐
小白不太白9505 小时前
设计模式之建造者模式
java·设计模式·建造者模式
菜菜-plus7 小时前
java 设计模式 模板方法模式
java·设计模式·模板方法模式
萨达大7 小时前
23种设计模式-模板方法(Template Method)设计模式
java·c++·设计模式·软考·模板方法模式·软件设计师·行为型设计模式
机器视觉知识推荐、就业指导9 小时前
C++设计模式:原型模式(Prototype)
c++·设计模式·原型模式
阳光开朗_大男孩儿9 小时前
组合模式和适配器模式的区别
设计模式·组合模式·适配器模式
MinBadGuy10 小时前
【GeekBand】C++设计模式笔记13_Flyweight_享元模式
c++·设计模式
Clang's Blog11 小时前
23种设计模式详解(以Java为例)
java·开发语言·设计模式
程序员奇奥11 小时前
设计模式——简单工厂模型、工厂模式、抽象工厂模式、单例模式、代理模式、模板模式
单例模式·设计模式·抽象工厂模式
hxj..11 小时前
【设计模式】代理模式
java·设计模式·代理模式·动态代理
十五年专注C++开发12 小时前
C++不完整类型(Incomplete Type)的检测与避免
开发语言·c++·算法·设计模式