设计模式轻松学【二一】组合模式

简介: 在现实生活中,存在很多“部分-整体”的关系,例如,大学中的部门与学院、总公司中的部门与分公司、学习用品中的书与书包等。在软件开发中也是这样,例如,文件系统中的文件与文件夹等。对这些简单对象与复合对象的处理,如果用组合模式来实现会很方便。

定义与特点

  • 定义

    又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。

    组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式能够将组合对象和简单对象进行一致处理的原因。

  • 参与角色

    • 抽象构件(Component)角色:为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。
    • 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,实现抽象构件角色中声明的公共接口。
    • 树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点。定义有枝节点的行为,用来存储子部件,实现了抽象构件中的有关操作,如增加(add)和删除(remove)、获取子节点(getChild)等

结构代码分析

组合模式分为透明式的组合模式和安全式的组合模式。

  1. 透明组合模式(推荐使用)

    在抽象构件中声明了所有来管理子对象的方法,其中包括add,remove等。这样实现抽象构件接口的所有子类都具备了add和remove方法。这样做的好处是叶节点和枝节点对于外界没有区别,它们具备完全一致的接口。

    image.png

    弊端:客户端对叶节点和枝节点是一致的,但叶节点并不具备add和remove的功能,因而对它们的实现是没有意义的,叶节点可通过抛出异常的方式来解决非法调用。

  2. 安全组合模式

    在抽象构件中不去声明add和remove方法,那么子类的Leaf就不需要实现它,而是在树枝构件中去声明所有用来管理子类对象的方法。

    image.png

    弊端:叶节点无需在实现add与remove这样的方法,但是对于客户端来说,必须对叶节点和枝节点进行判定,为客户端的使用带来不便。

  3. 结构代码

    这里以透明模式为例,实现集合 c0={leaf1,{leaf2,leaf3}}元素的访问,对应的树结构图如下:

    image.png

    • 声明抽象构件

      interface Component {
          public void add(Component c);
      
          public void remove(Component c);
      
          public Component getChild(int i);
      
          public void view();
      }
    • 声明树叶构件

      class Leaf implements Component {
          private String name;
      
          public Leaf(String name) {
              this.name = name;
          }
      
          public void add(Component c) {}
      
          public void remove(Component c) {}
      
          public Component getChild(int i) {
              return null;
          }
      
          public void view() {
              System.out.println("树叶" + name + ":被访问!");
          }
      }
    • 声明树枝构件

      class Composite implements Component {
          private ArrayList<Component> children = new ArrayList<Component>();
      
          public void add(Component c) {
              children.add(c);
          }
      
          public void remove(Component c) {
              children.remove(c);
          }
      
          public Component getChild(int i) {
              return children.get(i);
          }
      
          public void view() {
              for (Object obj : children) {
                  ((Component) obj).view();
              }
          }
      }
    • 测试程序调用

      public class ComponentTest {
      
          public static void main(String[] args) {
              Component c0 = new Composite(); 
              Component c1 = new Composite(); 
              
              Component leaf1 = new Leaf("1"); 
              Component leaf2 = new Leaf("2"); 
              Component leaf3 = new Leaf("3");  
              
              c0.add(leaf1); 
              c0.add(c1);
              c1.add(leaf2); 
              c1.add(leaf3);          
              c0.view(); 
          }
      }

总结

  • 优点

    • 可详细的定义分层次的复杂对象,用户可以忽略层次的差异。
    • 基本对象可以被组合成复杂组合对象,这个组合对象也可以被组合,这样不断递归,客户端调用基本对象的地方都可以使用组合对象。
    • 方便将新的叶子构件放入容器构件中。
  • 缺点

    层次关系的出现使得设计复杂。(所有设计模式共有的问题)

  • 适用场景

    • 当想表达对象的部分-整体的层次结构时
    • 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象时
目录
相关文章
|
3月前
|
设计模式
二十三种设计模式全面解析-组合模式与迭代器模式的结合应用:构建灵活可扩展的对象结构
二十三种设计模式全面解析-组合模式与迭代器模式的结合应用:构建灵活可扩展的对象结构
|
1月前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 组合模式
js设计模式【详解】—— 组合模式
34 7
|
2月前
|
设计模式 存储 安全
Java设计模式:组合模式之透明与安全的两种实现(七)
Java设计模式:组合模式之透明与安全的两种实现(七)
|
2月前
|
设计模式 Java
Java设计模式之组合模式详解
Java设计模式之组合模式详解
|
2月前
|
设计模式
组合模式-大话设计模式
组合模式-大话设计模式
11 0
|
3月前
|
设计模式 Java 容器
【设计模式系列笔记】组合模式
组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树状结构以表示部分-整体的层次结构。组合模式使得客户端可以统一处理单个对象和对象组合,而无需区分它们的类型。
67 12
|
3月前
|
设计模式 Go
[设计模式 Go实现] 结构型~组合模式
[设计模式 Go实现] 结构型~组合模式
|
3月前
|
设计模式 安全 Java
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
|
3月前
|
设计模式 Java
【设计模式】文件目录管理是组合模式吗?
【设计模式】文件目录管理是组合模式吗?
25 0
|
3月前
|
设计模式 存储 Java
23种设计模式,组合模式的概念优缺点以及JAVA代码举例
【4月更文挑战第5天】组合模式(Composite Pattern)是一种结构型设计模式,旨在通过将对象组合成树形结构以表示部分-整体的层次结构,使用户对单个对象和组合对象的使用具有一致性。这种模式让客户可以统一地处理单个对象和组合对象
58 6