1、Composite模式定义

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.

2、示例代码

类图:

类的一览表

定义Entry类

package cn.design.structured.compposite;

/**
* @author lin
* @version 1.0
* @date 2020-07-23 17:04
* @Description TODO
*/
public abstract class Entry {
   /**
    * 获取名字
    *
    * @return String
    */
   public abstract String getName();    /**
    * 获取大小
    *
    * @return int
    */
   public abstract int getSize();    /**
    * 加入目录条目
    *
    * @param entry 入参
    * @return 返回
    */
   public Entry add(Entry entry) {
       throw new FileTreatmentException();
  }    public void printList() {            // 显示目录条目
       printList("");
  }    protected abstract void printList(String prefix);  // 显示条目前缀    @Override
   public String toString() {
       return getName() + "(" + getSize() + ")";
  }
}

定义FileTreatmentException类

package cn.design.structured.compposite;

/**
* @author lin
* @version 1.0
* @date 2020-07-23 17:06
* @Description TODO
*/
public class FileTreatmentException extends RuntimeException {
   public FileTreatmentException() {
  }    public FileTreatmentException(String message) {
       super(message);
  } }

定义File类

package cn.design.structured.compposite;

/**
* @author lin
* @version 1.0
* @date 2020-07-23 17:05
* @Description 文件类
*/
public class File extends Entry {
   private String name;
   private int size;    public File(String name, int size) {
       this.name = name;
       this.size = size;
  }    @Override
   public String getName() {
       return name;
  }    @Override
   public int getSize() {
       return size;
  }    @Override
   protected void printList(String prefix) {
       System.out.println(prefix + "/" + this);
  }
}

定义Directory类

package cn.design.structured.compposite;

import java.util.ArrayList;
import java.util.Iterator; /**
* @author lin
* @version 1.0
* @date 2020-07-23 17:05
* @Description TODO
*/
public class Directory extends Entry {    private final String name;
   private final ArrayList<Entry> directory = new ArrayList<>();    public Directory(String name) {
       this.name = name;
  }    @Override
   public String getName() {
       return name;
  }    @Override
   public int getSize() {
       int size = 0;
       for (Entry entry : directory) {
           size += entry.getSize();
      }
       return size;
  }    @Override
   protected void printList(String prefix) {
       System.out.println(prefix + "/" + this);
       for (Entry entry : directory) {
           entry.printList(prefix + "/" + name);
      }
  }    @Override
   public Entry add(Entry entry) {
       directory.add(entry);
       return this;
  }
}

定义CompositeMain测试类

package cn.design.structured.compposite;

/**
* @author lin
* @version 1.0
* @date 2020-07-23 16:40
* @Description TODO
*/
public class CompositeMain {
   public static void main(String[] args) {
       try {
           System.out.println("Making root entries............");
           Entry rooter = new Directory("root");
           Entry binder = new Directory("bin");
           Entry teador = new Directory("tmp");
           Entry under = new Directory("usr");
           rooter.add(binder);
           rooter.add(teador);
           rooter.add(under);
           binder.add(new File("yi", 1000));
           binder.add(new File("latex", 200000));            System.out.println("");
           System.out.println("Making user entries......");
           Entry yuki = new Directory("yuki");
           Entry hanako = new Directory("tomura");
           Entry tomuura = new Directory("tomura");
           under.add(yuki);
           under.add(hanako);
           under.add(tomuura);
           yuki.add(new File("diary.html", 1000));
           rooter.printList();
      } catch (Exception e) {
           System.err.println();
      }
  }
}

运行结果如下:

Making root entries............

Making user entries......
/root(202000)
/root/bin(201000)
/root/bin/yi(1000)
/root/bin/latex(200000)
/root/tmp(0)
/root/usr(1000)
/root/usr/yuki(1000)
/root/usr/yuki/diary.html(1000)
/root/usr/tomura(0)
/root/usr/tomura(0)
与目标VM断开连接, 地址为: ''127.0.0.1:54150', transport: '套接字'', 传输: '{1}' Process finished with exit code 0

3、深入了解

复合模式类图

角色分工

◆Leaf(树叶)

表示“内容”的角色。在该角色中不能放入其他对象。在示例程序中,由File类扮演此角色。

◆Composite (复合物)

表示容器的角色。可以在其中放入Leaf角色和Composite角色。在示例程序中,由Di rectory类扮演此角色。

◆Component

使Leaf角色和Composite角色具有-致性的角色。Composite 角色是Leaf角色和Composite角色的父类。在示例程序中,由Entry类扮演此角色。

◆Client

使用Composite模式的角色。在示例程序中,由Main类扮演此角色。Composite模式的类图如图11-3 所示。在该图中,可以将Composite角色与它内部的Component角色(即Leaf角色或Composite角色)看成是父亲与孩子们的关系。getChild方法的作用是从Component角色获取这些“孩子们”。

4、小结

Composite比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。

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

主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

优点: 1、高层模块调用简单。2、节点自由增加。

缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

注意事项:定义时为具体类。

公众号:发哥讲

这是一个稍偏基础和偏技术的公众号,甚至其中包括一些可能阅读量很低的包含代码的技术文,不知道你是不是喜欢,期待你的关注。

如果你觉得文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈~

● 扫码关注我们

11、Composite 组合模式 容器与内容的一致性(抽象化) 结构型设计模式的更多相关文章

  1. 2、适配器 adapter 模式 加个"适配器" 以便于复用 结构型设计模式

    1.什么是适配器模式? 适配器如同一个常见的变压器,也如同电脑的变压器和插线板之间的电源连接线,他们虽然都是3相的,但是电脑后面的插孔却不能直接插到插线板上. 如果想让额定工作电压是直流12伏特的笔记 ...

  2. 设计模式(九):Composite组合模式 -- 结构型模式

    1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 我们可以使用简单的对象组合成复杂的对象,而这个复杂对 ...

  3. 一天一个设计模式——Composite组合模式

    一.模式说明 能够使容器与内容物具有一致性,创造出递归结构的模式就是Composite组合模式. 举个例子:计算机中的文件系统中有文件和文件夹的概念,我们知道,文件夹可以包含文件,也可以包含子文件夹, ...

  4. Composite组合模式(结构型模式)

    1.概述 在面向对象系统中,经常会遇到一些具有"容器性质"的对象,它们自己在充当容器的同时,也充当其他对象的容器. 2.案例 需要构建一个容器系统,需要满足以下几点要求: (1). ...

  5. 设计模式08: Composite 组合模式(结构型模式)

    Composite 组合模式(结构型模式) 对象容器的问题在面向对象系统中,我们常会遇到一类具有“容器”特征的对象——即他们在充当对象的同时,又是其他对象的容器. public interface I ...

  6. C++设计模式-Composite组合模式

    Composite组合模式作用:将对象组合成树形结构以表示“部分-整体”的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. UML图如下: 在Component中声明所有用来 ...

  7. 组合模式 合成模式 COMPOSITE 结构型 设计模式(十一)

    组合模式(合成模式 COMPOSITE) 意图 将对象组合成树形结构以表示“部分-整体”的层次结构. Composite使得用户对单个对象和组合对象的使用具有一致性.   树形结构介绍 为了便于理解, ...

  8. 十一、Composite 组合模式

    原理: 代码清单 Entity public abstract class Entry { public abstract String getName(); public abstract int ...

  9. 享元模式 FlyWeight 结构型 设计模式(十五)

    享元模式(FlyWeight)  “享”取“共享”之意,“元”取“单元”之意. 意图 运用共享技术,有效的支持大量细粒度的对象. 意图解析 面向对象的程序设计中,一切皆是对象,这也就意味着系统的运行将 ...

随机推荐

  1. 机器学习实战基础(十二):sklearn中的数据预处理和特征工程(五) 数据预处理 Preprocessing & Impute 之 处理分类特征:处理连续性特征 二值化与分段

    处理连续性特征 二值化与分段 sklearn.preprocessing.Binarizer根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量.大于阈值的值映射为1,而小于或等于阈值的值 ...

  2. python 之 编码

    本节内容 编码回顾 编码转换 Python的bytes类型 编码回顾 在备编码相关的课件时,在知乎上看到一段关于Python编码的回答 这哥们的这段话说的太对了,搞Python不把编码彻底搞明白,总有 ...

  3. 使用OpenCV对图片进行特征点检测和匹配(C++)

    背景 最近从不同网站下载了非常多的动漫壁纸,其中有一些内容相同,但是大小.背景颜色.色调.主人公的位置不同(例子如下).正因为如此,基础的均方误差.直方图检测等方法很难识别出这些相似的图片. 思路 O ...

  4. Ethical Hacking - NETWORK PENETRATION TESTING(17)

    MITM - bypassing HTTPS Most websites use https in their login pages, this means that these pages are ...

  5. scratch编程——画笔模块画各种同心图案

    我们今天是要用画笔来画出不同的同心图案,在画之前,我们先来了解一下画笔模块: 1.画笔模块的用法 画笔模块的用法就是在舞台上留下不同颜色粗细的线条,它的默认是情况是抬笔,我们在使用的时候要让角色移动到 ...

  6. 题解 洛谷 P3521 【[POI2011]ROT-Tree Rotations】

    给定一棵二叉树,叶子节点有权值,可以进行若干次交换一个节点的左右儿子的操作,使前序遍历叶子的逆序对最少. 考虑一个节点下子树逆序对的产生: ① 只在左子树中产生. ② 只在右子树中产生. ③ 在左子树 ...

  7. Android Studio常见问题集锦

    Android studio无法在可视化页面预览XML布局文件 修改res/values/styles.xml文件中name=“AppTheme”的style,在Theme.AppCompat.Lig ...

  8. 新款iPad Pro4的电池续航和充电速度对比

    3月18日晚苹果官网上架了两款新iPad Pro,两款iPad Pro 2020外观大小分别为11英寸和12.9英寸,搭载苹果A12Z仿生芯片,起售价分别为6288元和7899元.那么两款iPad P ...

  9. Promise对象 异步编程

    Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是 ...

  10. 【Laravel】为Eloquent 模型设置全局作用域和局部作用域进行查询

    全局作用域 所谓「全局作用域」,指的是预置过滤器在注册该「全局作用域」的模型类的所有查询中生效,不需要指定任何额外条件. 以 User 模型类为例,我们在系统中可能只想针对已经验证过邮箱的用户进行操作 ...