Java设计模式之组合模式

概述

组合模式也称为部分整体模式,是结构型设计模式,组合模式将一组相似的对象看作一个对象处理.
并根据一个树状结构来组合对象,然后提供一个统一的方法去访问相应的对象,以此忽略掉对象与对象集合之间的差别.当组合体一个对象的一个方法被调用执行时,
Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行

定义

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

使用场景

  • 表示对象的部分-整体层次结构时
  • 从一个整体中能够独立出部分模块或功能的场景

UML

组合模式UML

其中涉及到的角色介绍:

  • Component : 抽象根节点,在适当的情况下,实现所有类共有接口的缺省行为.声明一个接口用于访问和管理Component
    子部件。
  • Composite : 定义有子节点的那些枝干节点的行为,存储子节点,在Component接口中实现与子节点有关的操作
  • Leaf : 在组合中表示叶子节点对象,叶子节点没有子节点,在组合中定义节点对象的行为.
  • Client : 客户端对象,通过Component操作组合节点的对象

实例

比较典型的组合模式使用场景就是文件夹系统了,如下就是通过文件夹模拟组合模式的使用

  • 首先定义文件和文件夹的抽象,相当于Component角色
public abstract class Dir {
  /**
   * 声明一个List成员变量存储文件夹下的所有元素
   */
  protected List<Dir>mDirs = new ArrayList<>();

  private String name;

  public Dir(String _name) {
    name = _name;
  }

  public abstract void addDir(Dir _dir);

  public abstract void rmDir(Dir _dir);

  public abstract void clear();

  public abstract void print();

  public abstract List<Dir> getFiles();

  public String getName() {
    return name;
  }
}
  • 接下来定义文件夹对象,相当于Composite
public class Folder extends Dir {
  private static final String TAG = "Folder";

  public Folder(String _name) {
    super(_name);
  }

  @Override public void addDir(Dir _dir) {
    mDirs.add(_dir);
  }

  @Override public void rmDir(Dir _dir) {
    mDirs.remove(_dir);
  }

  @Override public void clear() {
    mDirs.clear();
  }

  @Override public void print() {
    Log.d(TAG, "print: --->" + getName() + "(");
    Iterator<Dir> iter = mDirs.iterator();
    while (iter.hasNext()) {
      Dir dir = iter.next();
      dir.print();
      if (iter.hasNext()) {
        Log.d(TAG, "print: -->" + ",");
      }
    }
    Log.d(TAG, "print: -->" + ")");
  }

  @Override public List<Dir> getFiles() {
    return mDirs;
  }
}
  • 文件对象,没有子节点,相当于Leaf
public class File extends Dir {
  private static final String TAG = "File";
  public File(String _name) {
    super(_name);
  }

  @Override public void addDir(Dir _dir) {
    throw new UnsupportedOperationException("文件对象不支持该操作");
  }

  @Override public void rmDir(Dir _dir) {
    throw new UnsupportedOperationException("文件对象不支持该操作");
  }

  @Override public void clear() {
    throw new UnsupportedOperationException("文件对象不支持该操作");
  }

  @Override public void print() {
    Log.d(TAG, "print: -->"+getName());
  }

  @Override public List<Dir> getFiles() {
    throw new UnsupportedOperationException("文件对象不支持该操作");
  }
}
  • Client客户端对象调用示例
Dir diskC = new Folder("C");
    diskC.addDir(new File("sss.text"));

    Dir dirW = new Folder("Windows");
    dirW.addDir(new File("explorer.exe"));
    Dir dirP = new Folder("PerfLogs");
    dirP.addDir(new File("bbb.text"));
    Dir dirF = new Folder("Program File");
    dirF.addDir(new File("ftp.text"));

    diskC.addDir(dirW);
    diskC.addDir(dirP);
    diskC.addDir(dirF);

    diskC.print();

模式特点

优点:

  • 组合模式可以清楚的定义分层次的复杂对象,表示对象的全部或部分层次.同时,让高层次模块忽略了层次的差异,方便对整个层次结构进行控制.
  • 高层模块可以一致的使用一个组合结构或其中的单个对象,不用关心处理的是单个对象还是组合结构.
  • 新增新的枝干构件很方便,无需修改原来的文件,符合开闭原则.

缺点:

  • 在新增构件时不好对枝干中的构件类型进行限制,不能依赖类型系统来施加这些约束,因为他们都来自形同的抽象层.

实例代码

DesignPatterns

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值