• 设计模式中的组合模式
  • 发布于 2个月前
  • 236 热度
    0 评论
概念
又名部分整体模式,是用于把一组相似的对象当做一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层级

结构
抽象根节点:定义系统中各个层次对象的共有方法、属性,可以预先定义一些默认行为和属性
树状节点:定义树枝节点的行为,存储子节点,组合树枝节点、叶子节点形成一个树形结构
叶子节点:是系统层级遍历的最小单位,其下再无分支

示例
目标:构建一个文件系统,文件夹下存储文件夹、文件

抽象根节点
import lombok.Getter;

/**
 * 堆代码 duidaima.com
 * 文件系统组件:抽象根节点
 */
@Getter
public abstract class FileSystemComponent {

  /** 名称 */
  protected String name;
  /** 层级 */
  protected int level = 0;

  /**
   * 增加一个子级组件
   */
  void add(FileSystemComponent component) {
    throw new UnsupportedOperationException();
  }

  /**
   * 删除一个子级组件
   */
  void remove(FileSystemComponent component) {
    throw new UnsupportedOperationException();
  }

  /**
   * 打印自身、所有子级的名称
   */
  abstract void print();

}

树状节点
import java.util.ArrayList;
import java.util.List;

/**
 * 目录:树枝节点
 */
public class Dir extends FileSystemComponent {

  /** 子级组件 */
  List<FileSystemComponent> sonList = new ArrayList<>();

  /**
   * 构造方法
   */
  Dir(String name) {
    this.name = name;
  }

  /**
   * 增加一个子级组件
   */
  void add(FileSystemComponent component) {
    // 层级+1
    component.level = getLevel() + 1;
    // 添加数据
    sonList.add(component);
  }

  /**
   * 删除一个子级组件
   */
  void remove(FileSystemComponent component) {
    sonList.remove(component);
  }

  @Override
  void print() {
    // 打印当前
    for (int i = 0; i < getLevel(); i++) {
      System.out.print("  ");
    }
    System.out.println(getName());

    // 打印子级
    for (FileSystemComponent component : sonList) {
      component.print();
    }
  }

}
叶子节点
/**
 * 目录:叶子节点
 */
public class File extends FileSystemComponent {

  /**
   * 构造方法
   */
  File(String name) {
    this.name = name;
  }

  @Override
  void print() {
    for (int i = 0; i < getLevel(); i++) {
      System.out.print("  ");
    }
    System.out.println(getName());
  }

}
测试类
public class Demo {

  public static void main(String[] args) {
    // 根目录
    Dir root = new Dir("个人学习资料库");
    // 堆代码 duidaima.com
    // 一层目录
    Dir first_front = new Dir("前端");
    Dir first_background = new Dir("后台");
    // 将一层目录加入根目录中
    root.add(first_front);
    root.add(first_background);

    // 二层目录、文件
    Dir second_front_css = new Dir("CSS");
    Dir second_front_typeScript = new Dir("TypeScript");
    File second_background_mybatis = new File("Mybatis.docx");
    Dir second_background_spring = new Dir("Spring大全");
    // 将二层目录、文件加入一层目录中
    first_front.add(second_front_css);
    first_front.add(second_front_typeScript);
    first_background.add(second_background_mybatis);
    first_background.add(second_background_spring);

    // 打印根目录结构
    root.print();
  }

}
优缺点
优点
1.组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便了对整体层次结构进行控制
2.客户端可以一致的使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
3.新增树状节点、叶子节点时符合开闭原则,不必对现有代码进行任何修改

应用场景
需要用到树状结构的地方都可以使用组合模式
用户评论