前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >组合模式浅析

组合模式浅析

作者头像
孟君
发布2020-06-28 15:57:41
4490
发布2020-06-28 15:57:41
举报
文章被收录于专栏:孟君的编程札记

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

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

一. 组合模式的基本介绍

意图

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

结构

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

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

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

参与者如何协作?

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

二. 组合模式的示例

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

  • Entry(Component角色)

代码语言:javascript
复制
package com.wangmengjun.tutorial.designpattern.composite;

public abstract class Entry {

   abstract void add(Entry e);

   abstract void list();

}
  • File(Leaf角色)
代码语言:javascript
复制
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(树枝角色)
代码语言:javascript
复制
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角色)
代码语言:javascript
复制
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(); 
  }
} 

运行一下:

代码语言:javascript
复制
音乐/
音乐/冰雨.mp3
音乐/吻别.mp3
音乐/等一分钟.mp3
音乐/小镇姑娘.mp3
音乐/一千个伤心的理由.mp3
音乐/空目录/

三. 小结

优缺点

优点:

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

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

缺点:

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

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

参考

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 孟君的编程札记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 组合模式的基本介绍
  • 二. 组合模式的示例
  • 三. 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档