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. python 以行为单位进行字符串的切割

    可以使用str 的 splitlines() 方法 实现以行为单位 进行字符串的切割, keepends=False 不保留\n符号, kendends=True 保留\n符号 my_str = &q ...

  2. IOS 开发入门

    1.Getting Started https://developer.apple.com/library/ios/navigation/#section=Resource%20Types&t ...

  3. Kafka数据可靠性与一致性解析

    Partition Recovery机制 每个Partition会在磁盘记录一个RecoveryPoint, 记录已经flush到磁盘的最大offset.broker fail 重启时,会进行load ...

  4. Jmeter Cannot load JDBC driver class 'com.mysql.jdbc.Driver'问题解决方案

    1.下载 mysql-connector-java-5.1.44-bin.jar,哪个版本都可以,按自己的mysql版本来 2.将jar包放到jmeter安装路径下的 apache-jmeter-3. ...

  5. leetcode-914-卡牌分组

    题目描述: 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的整数. 仅当你可选的 ...

  6. POJ 1147

    #include <iostream> #include <algorithm> #define MAXN 3005 using namespace std; int _m[M ...

  7. Linux终端复用工具 tmux

    简介 Terminal Multiplexer (From WIKIPEDIA) - A terminal multiplexer is a software application that can ...

  8. JSON JSONPath

    JSONPath is a query language for JSON, similar to XPath for XML. AlertSite API endpoint monitors let ...

  9. linux下shell脚本执行方法及exec和source命令

    exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息. bash shell的命令分为两 ...

  10. HTML页面的重绘(repaint)和重流(reflow)

    重流(Reflow)是指布局引擎为frame计算图形的过程. frame是一个矩形,拥有宽高和相对父容器的偏移.frame用来显示盒模型(content model), 但一个content mode ...