组合模式浅析

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

在平时,我们在应用中碰到的文件系统(文件是叶子节点,文件目录是树枝节点,可以包含文件或文件目录);企业结构(企业有很多部门,部分有些是没有下属部门,有些是有的);另外,还有向分类层级关系等,这些都可以看做是组合模式的典型应用。

一. 组合模式的基本介绍

意图

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。

结构

组合模式的基本结构如下:

这里涉及到的参与者有如下几种:

  • Component角色
    • 这是一抽象角色,它给参加组合的对象规定一个接口,规范共有的接口及默认行为。
  • Leaf角色
    • 在组合中表示叶节点对象,叶子节点没有子节点。
  • Composite角色
    • 代表参加组合的有子对象的对象,定义出这样的对象的行为。
  • Client角色
    • 通过Component接口操纵组件的对象

参与者如何协作?

用户使用Component类接口与组合结构中的对象进行交互。如果接收者是一个叶子节点,则直接处理请求。如果接收者是Composite,它通常将请求发送给它的子部件,在转发请求之前与/或之后可能执行一些辅助操作。

二. 组合模式的示例

接下来以一个文件、目录的示例来说明一下组合模式。其中File是叶子节点,Directory是Composite构件。

  • Entry(Component角色)

package com.wangmengjun.tutorial.designpattern.composite;

public abstract class Entry {

   abstract void add(Entry e);

   abstract void list();

}
  • File(Leaf角色)
package com.wangmengjun.tutorial.designpattern.composite;

public class File extends  Entry {

  private String name;

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

  @Override
  public void list() {
    System.out.println(name);

  }

  /**
   * @return the name
   */
  public String getName() {
    return name;
  }

  @Override
  void add(Entry e) {
    //叶子节点不能添加子节点,dothing 
  }
  

}
  • Directory(树枝角色)
package com.wangmengjun.tutorial.designpattern.composite;

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

public class Directory extends Entry {

 private String name;
 private List<Entry> childEntryList = new ArrayList<>();
  
  public Directory(String name) {
    this.name = name;
  }

  

  @Override
  void add(Entry e) {
    childEntryList.add(e);

  }

  @Override
  public void list() {
    String currDir = this.getName() + "/";
    System.out.println(currDir);
    for(Entry entry : childEntryList) {
      System.out.print(currDir);
      entry.list();

    }

  }

  /**
   * @return the name
   */
  public String getName() {
    return name;
  }
}
  • Client(Client角色)
package com.wangmengjun.tutorial.designpattern.composite;

public class Client {
  public static void main(String[] args) {
        Entry music = new Directory("音乐");

          Entry music1 = new File("冰雨.mp3");
          Entry music2 = new File("吻别.mp3");
          Entry music3 = new File("等一分钟.mp3");
          Entry music4 = new File("小镇姑娘.mp3");
          Entry music5 = new File("一千个伤心的理由.mp3");
          music.add(music1);
          music.add(music2);
          music.add(music3);
          music.add(music4);
          music.add(music5);

          Entry enpty = new Directory("空目录");
          music.add(enpty);

          music.list(); 
  }
} 

运行一下:

音乐/
音乐/冰雨.mp3
音乐/吻别.mp3
音乐/等一分钟.mp3
音乐/小镇姑娘.mp3
音乐/一千个伤心的理由.mp3
音乐/空目录/

三. 小结

优缺点

优点:

(1):组合模式可以很容易地增加新种类的构件

(2):使用组合模式可以使客户端变得容易设计,因为客户端不需要知道构件是树叶构件还是树枝构件。

缺点:

(1):使用组合模式后,控制树枝构件的类型就不太容易

(2):用继承的方法来增加新的行为会变得困难。

参考

[1]. 阎宏. Java与模式.电子工业出版社

[2]. Erich Gamma. 设计模式-可复用面向对象软件的基础. 机械工业出版社.

本文分享自微信公众号 - 孟君的编程札记(gh_0f0f5e0ae1de),作者:孟君

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设计模式几大原则

    单一职责原则(Single Responsibility Principle,SRP):一个类只负责一个功能领域中的相应职责或可以定义为:就一个类而言,应该只有...

    孟君
  • 一步步完成jsRender + Spring MVC + Nginx前后端分离示例

    本篇博文的目标是使用前端页面渲染插件jsRender做前后端分离,后端采用Spring MVC给出REST API,并结合Nginx完成配置。

    孟君
  • 享元模式浅析

    面向对象技术可以很好地解决一些灵活性或可以扩展性问题,但是很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致对象创建以及垃圾回收的代价过高,造成...

    孟君
  • Flutter lesson 9: Flutter的网络(HTTP)请求

    Flutter中网络请求有两种,一个是使用Flutter自带的网络请求,另一种则是使用第三方HTTP请求插件dio

    踏浪
  • Python网络爬虫(四)- XPath1.XPath2.XPath在python中的应用

    XPath 即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。它使用路径表达式来选取 XML 文档中的节点...

    意气相许的许
  • Zookeeper系列(7) —— Zookeeper 的 Java API

    在使用 Java API 对 Zookeeper 进行操作是,首先需要引入相关的依赖。

    求和小熊猫
  • Java基础(01)-15总结对象数组,集合Collection,集合List

    1:对象数组(掌握) (1)数组既可以存储基本数据类型,也可以存储引用类型。它存储引用类型的时候的数组就叫对象数组。 (2)案例: 用数组存储5个学生对象...

    Java帮帮
  • Java设计模式之模板方法模式

    假设我们现在要造一批悍马汽车,悍马汽车有两个系列H1和H2,首先不考虑任何设计模式,看看设计的类图:

    CoderJed
  • JavaWeb——Struts2

    Struts2是一个基于MVC设计模式web应用框架,在webwork框架技术基础上,Strurts2核心是拦截器,Struts2框架的核心功能都依靠拦截器实现...

    羊羽shine
  • 大话设计模式--第一章 简单工厂设计模式

    从这四个方面考虑. 上面这段代码, 维护性差, 改一个地方很可能或误改正确的地方; 复用性, 除了计算器, 其他地方基本不可用. 扩展性也不好, 添加一个开方,...

    用户7798898

扫码关注云+社区

领取腾讯云代金券