设计模式之组合模式

组合模式

文章目录

定义

组合模式(Composite Pattern)也叫合成模式,有时又叫做部分-整体模式(Part-Whole),主要是用来描述部分与整体的关系,其定义如下:

Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual objects and compositions of objects uniformly.(将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。)

我们先来说说组合模式的几个角色:

  1. Component抽象构件角色

定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性,比如我们例子中的getInfo就封装到了抽象类中。

·Leaf叶子构件

叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。

  1. Composite树枝构件

树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。

优缺点

优点
  1. 高层模块调用简单

    一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,也就是说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。

  2. 节点自由增加

    使用了组合模式后,我们可以看看,如果想增加一个树枝节点、树叶节点是不是都很容易,只要找到它的父节点就成,非常容易扩展,符合开闭原则,对以后的维护非常有利。

缺点

组合模式有一个非常明显的缺点,看到我们在场景类中的定义,提到树叶和树枝使用时的定义了吗?直接使用了实现类!这在面向接口编程上是很不恰当的,与依赖倒置原则冲突。

示例代码

  1. 抽象类组件
java 复制代码
public abstract class Component {
    public void doSomething() {
        System.out.println("component do something");
    }
}
  1. 组合类

    java 复制代码
    public class Composite extends Component {
        // 构件容器
        private List<Component> componentArrayList = new ArrayList<Component>();
    
        // 增加一个叶子构件或树枝构件
        public void add(Component component) {
            this.componentArrayList.add(component);
        }
    
        // 删除一个叶子构件或树枝构件
        public void remove(Component component) {
            this.componentArrayList.remove(component);
        }
    
        // 获得分支下的所有叶子构件和树枝构件
        public List<Component> getChildren() {
            return this.componentArrayList;
        }
    }
  2. 叶子节点

    java 复制代码
    public class Leaf extends Component {
        @Override
        public void doSomething() {
            System.out.println("leaf do something");
        }
    }
  3. 测试方法

    java 复制代码
    @Test
    public void test() {
        // 创建一个根节点
        Composite root = new Composite();
        root.doSomething();
        // 创建一个树枝构件
        Composite branch = new Composite();
        // 创建一个叶子节点
        Leaf leaf = new Leaf();
        // 建立整体
        root.add(branch);
        branch.add(leaf);
        display(root);
    }
    
    // 通过递归遍历树
    public static void display(Composite root) {
        for (Component c : root.getChildren()) {
            if (c instanceof Leaf) { // 叶子节点
                c.doSomething();
            } else { // 树枝节点
                display((Composite)c);
            }
        }
    }

运行结果

component do something
leaf do something

示例代码地址

https://gitee.com/youxiaxiaomage/java-practices/tree/master/yxxmg-gof-sample/src/main/java/com/yxxmg/gof/structure/composite

相关推荐
小白不太白9506 分钟前
设计模式之 观察者模式
观察者模式·设计模式
小白不太白9501 小时前
设计模式之 责任链模式
python·设计模式·责任链模式
吾与谁归in2 小时前
【C#设计模式(13)——代理模式(Proxy Pattern)】
设计模式·c#·代理模式
吾与谁归in2 小时前
【C#设计模式(14)——责任链模式( Chain-of-responsibility Pattern)】
设计模式·c#·责任链模式
闲人一枚(学习中)2 小时前
设计模式-创建型-原型模式
设计模式
Iced_Sheep2 小时前
干掉 if else 之策略模式
后端·设计模式
哪 吒10 小时前
最简单的设计模式,抽象工厂模式,是否属于过度设计?
设计模式·抽象工厂模式
Theodore_102210 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
转世成为计算机大神13 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
小乖兽技术14 小时前
23种设计模式速记法
设计模式