Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。 

  组合(Composite)模式的其它翻译名称也很多,比如合成模式、树模式等等。在《设计模式》一书中给出的定义是:将对象以树形结构组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。

  从定义中可以得到使用组合模式的环境为:在设计中想表示对象的“部分-整体”层次结构;希望用户忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象。

  

  组合模式的角色和职责

  1、Component (树形结构的节点抽象)

    1.1、为所有的对象定义统一的接口(公共属性,行为等的定义)

    1.2、提供管理子节点对象的接口方法

    1.3、[可选]提供管理父节点对象的接口方法

  2、Leaf (树形结构的叶节点)

    Component的实现子类

  3、Composite(树形结构的枝节点)

    Component的实现子类

  安全性与透明性

  组合模式中必须提供对子对象的管理方法,不然无法完成对子对象的添加删除等等操作,也就失去了灵活性和扩展性。但是管理方法是在Component中就声明还是在Composite中声明呢?

  一种方式是在Component里面声明所有的用来管理子类对象的方法,以达到Component接口的最大化(如下图所示)。目的就是为了使客户看来在接口层次上树叶和分支没有区别——透明性。但树叶是不存在子类的,因此Component声明的一些方法对于树叶来说是不适用的。这样也就带来了一些安全性问题。

  另一种方式就是只在Composite里面声明所有的用来管理子类对象的方法(如下图所示)。这样就避免了上一种方式的安全性问题,但是由于叶子和分支有不同的接口,所以又失去了透明性。

  《设计模式》一书认为:在这一模式中,相对于安全性,我们比较强调透明性。对于第一种方式中叶子节点内不需要的方法可以使用空处理或者异常报告的方式来解决。

  我们举个例子,比如说文件夹与文件,层次结构就符合树形结构

  首先我们新建一个Component接口(树形结构的节点抽象)

 /*
* 文件节点抽象(是文件和目录的父类)
*/
public interface IFile { //显示文件或者文件夹的名称
public void display(); //添加
public boolean add(IFile file); //移除
public boolean remove(IFile file); //获得子节点
public List<IFile> getChild();
}

  该例子符合透明性,如果是安全性,将IFile中的方法去除,不在IFile声明,直接在子类中声明即可。

  接下来,创建一个Leaf(叶子结点),因为文件是不可再分的,所以File是叶子结点

 /*
* 文件(leaf 叶子结点)
*/
public class File implements IFile {
private String name; public File(String name) {
this.name = name;
} public void display() {
System.out.println(name);
} public List<IFile> getChild() {
return null;
} public boolean add(IFile file) {
return false;
} public boolean remove(IFile file) {
return false;
} }

  然后继续创建Composite(文件夹),因为文件夹下面还可能有文件与文件夹,所以是composite

 public class Folder implements IFile{
private String name;
private List<IFile> children; public Folder(String name) {
this.name = name;
children = new ArrayList<IFile>();
} public void display() {
System.out.println(name);
} public List<IFile> getChild() {
return children;
} public boolean add(IFile file) {
return children.add(file);
} public boolean remove(IFile file) {
return children.remove(file);
}
}

  然后是客户端,用递归的形式把这个具有树形结构的对象遍历出来

 public class MainClass {
public static void main(String[] args) {
//C盘
Folder rootFolder = new Folder("C:");
//C盘下的目录一
Folder folder1 = new Folder("目录一");
//C盘下的文件一
File file1 = new File("文件一.txt"); rootFolder.add(folder1);
rootFolder.add(file1); //目录一下的目录二
Folder folder2 = new Folder("目录二");
//目录一下的文件二
File file2 = new File("文件二.txt");
folder1.add(folder2);
folder1.add(file2); //目录二下的目录三
Folder folder3 = new Folder("目录三");
//目录二下的文件三
File file3 = new File("文件三.txt");
folder2.add(folder3);
folder2.add(file3); displayTree(rootFolder,0); } public static void displayTree(IFile rootFolder, int deep) {
for(int i = 0; i < deep; i++) {
System.out.print("--");
}
//显示自身的名称
rootFolder.display();
//获得子树
List<IFile> children = rootFolder.getChild();
//遍历子树
for(IFile file : children) {
if(file instanceof File) {
for(int i = 0; i <= deep; i++) {
System.out.print("--");
}
file.display();
}else {
displayTree(file,deep + 1);
}
}
}
}

  这样子,就把,这棵树遍历了出来。

  优缺点

    优点:

    1) 使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关心自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。

    2)更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。这一点符合开闭原则的要求,对系统的二次开发和功能扩展很有利!

    缺点:

    组合模式不容易限制组合中的构件。

  总结

  组合模式是一个应用非常广泛的设计模式,它本身比较简单但是很有内涵,掌握了它对你的开发设计有很大的帮助。

java设计模式-----13、组合模式的更多相关文章

  1. java设计模式之组合模式

    组合模式 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 & ...

  2. Java设计模式应用——组合模式

    组合模式实际上是一种树形数据结构.以windows目录系统举例,怎么样用java语言描述一个文件夹? 定义一个文件夹类,文件夹类中包含若干个子文件类和若干个文件类. 进一步抽象,把文件夹和文件都看做节 ...

  3. java设计模式5.组合模式、门面模式、享元模式、桥接模式

    组合模式 在面向对象的语言中,树结构有着巨大的威力,一个基于继承的类型的等级结构便是一个数结构,一个基于合成的对象结构也是一个数结构.组合模式将部分与整体的关系用树结构表示出来,使得客户端把一个个单独 ...

  4. JAVA设计模式之组合模式(composite)

    组合模式:树状结构专用模式 代码如下: package com.srr.dp.composite; import java.util.ArrayList; import java.util.List; ...

  5. JS常用的设计模式(13)——组合模式

    组合模式又叫部分-整体模式,它将所有对象组合成树形结构.使得用户只需要操作最上层的接口,就可以对所有成员做相同的操作. 一个再好不过的例子就是jquery对象,大家都知道1个jquery对象其实是一组 ...

  6. JavaScript设计模式-13.组合模式

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. 老和尚给小和尚讲故事引发了Java设计模式:组合模式

    目录 示例 组合模式 定义 意图 主要解决问题 优缺点 安全式和透明式的组合模式 安全式的合成模式的结构 透明式的合成模式的结构 老和尚和小和尚的故事 示例 有一个绘图系统,可以描绘各种图形,假设现在 ...

  8. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  9. JAVA设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

  10. 折腾Java设计模式之访问者模式

    博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...

随机推荐

  1. 内置装饰器二:@property

    property 装饰器的作用 property 装饰器将方法包装成属性,将私有属性公有化,此属性只能被读取.相当于实现get方法的对象 class People: def __init__(self ...

  2. Python 读取大文件的方式

    对于读取容量小的文件,可以使用下面的方法: with open("path", "r") as f: f.read() 但是如果文件容量很大,高达几个G或者十几 ...

  3. easyui页面上字段排序并与后台交互

    在开始对easyui里面页面上进行排序,感觉应该不怎么难,但是在操作的时候并没有那么简单,上网也查了很多进行排序的方法,最终总结出这个方法,供大家参考使用: 一.在easyui里面上只需 1.将要进行 ...

  4. Swift 里字符串(二)创建

     最终都要走到__StringStorage 的 create(realCodeUnitCapacity,countAndFlags) 方法里去. 默认实现是 UTF8 internal stati ...

  5. Python小白学习之路(二十二)—【生成器】

    一.什么是生成器? 生成器可以理解成是一种数据类型,特殊地是生成器可以自动实现迭代器协议其他的数据类型需要调用自己内置的__iter__方法所以换种说法,生成器就是可迭代对象 !回忆:很重要的迭代器协 ...

  6. js集合set类的实现

    js集合set类的实现 /*js集合set类的实现*/ function Set() { this.dataStore = []; this.add = add;//新增元素 this.remove ...

  7. linux 手动释放buff/cache

    为了解决buff/cache占用过多的问题执行以下命令即可 syncecho 1 > /proc/sys/vm/drop_cachesecho 2 > /proc/sys/vm/drop_ ...

  8. springboot打包成jar包后找不到xml,找不到主类的解决方法

    springboot打包成jar包后找不到xml,找不到主类的解决方法 请首先保证你的项目能正常运行(即不打包的时候运行无误),我们在打包时经常遇到如下问题: springboot打包成jar包后找不 ...

  9. java数据结构之递归算法

    概述程序调用自身的编程技巧称为递归( recursion).递归做为一种算法在程序设计语言中广泛应用.递归有直接递归和间接递归•直接递归:函数在执行过程中调用本身.•间接递归:函数在执行过程中调用其它 ...

  10. Windows环境下执行hadoop命令出现Error: JAVA_HOME is incorrectly set Please update D:\SoftWare\hadoop-2.6.0\conf\hadoop-env.cmd错误的解决办法(图文详解)

    不多说,直接上干货! 导读   win下安装hadoop 大家,别小看win下的安装大数据组件和使用  玩过dubbo和disconf的朋友们,都知道,在win下安装zookeeper是经常的事   ...