1 基础知识

定义:将对象组合成树形结构以表示“部分-整体”的层次结构。特征:组合模式使得客户端对单个对象和组合对象保持一致的方式处理。

本质:统一叶子对象和组合对象。

目的:让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作。

使用场景:希望客户端可以忽略组合对象与单个对象的差异;处理一个树形结构时。

优点:清楚定义分层次的复杂对象,表示对象的全部或部分层次;让客户端忽略了层次的差异,方便对整个层次结构控制;更容易扩展;符合开闭原则。缺点:限制类型时会比较复杂;使设计变得更加抽象。

2 代码示例:

使用场景:以慕课网为例,有一个Java课程目录,在这目录下有多种Java课程,如果把具体的Java课程继承课程目录那么就可以视课程目录与具体课程为同一对象操作。

对于课程目录可以的显示方式如下:利用空格缩进表示主目录和子目录

抽象目录组件:CatalogComponent

public abstract class CatalogComponent {

    public void add(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持添加操作");
} public void remove(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持删除操作");
} public String getName(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持获取名称操作");
} public double getPrice(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持获取价格操作");
} public void print(){
throw new UnsupportedOperationException("不支持打印操作");
}
}

课程类:Course

public class Course extends CatalogComponent {
//课程名称
private String name;
//课程价格
private double price; public Course(String name, double price) {
this.name = name;
this.price = price;
} @Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
} @Override
public double getPrice(CatalogComponent catalogComponent) {
return this.price;
} @Override
public void print() {
System.out.println("Course Name:"+name+" Price:"+price);
}
}

课程目录:CourseCatalog

public class CourseCatalog extends CatalogComponent {
//在课程目录中会有许多课程,这些课程又属于目录组件
private List<CatalogComponent> items = new ArrayList<CatalogComponent>();
private String name;
//为了使输出的排版更清晰
private Integer level; public CourseCatalog(String name,Integer level) {
this.name = name;
this.level = level;
} @Override
public void add(CatalogComponent catalogComponent) {
items.add(catalogComponent);
} @Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
} @Override
public void remove(CatalogComponent catalogComponent) {
items.remove(catalogComponent);
} @Override
public void print() {
System.out.println(this.name);
for(CatalogComponent catalogComponent : items){
if(this.level != null){
for(int i = 0; i < this.level; i++){
System.out.print(" ");
}
}
catalogComponent.print();
}
}
}

应用层:

public class Test {
public static void main(String[] args) {
CatalogComponent linuxCourse = new Course("Linux课程",11);
CatalogComponent windowsCourse = new Course("Windows课程",11);
//Java课程目录为2级目录
CatalogComponent javaCourseCatalog = new CourseCatalog("Java课程目录",2); CatalogComponent mmallCourse1 = new Course("Java电商一期",55);
CatalogComponent mmallCourse2 = new Course("Java电商二期",66);
CatalogComponent designPattern = new Course("Java设计模式",77);
//把课程添加到java课程目录中
javaCourseCatalog.add(mmallCourse1);
javaCourseCatalog.add(mmallCourse2);
javaCourseCatalog.add(designPattern);
//网站课程主目录级别为1
CatalogComponent imoocMainCourseCatalog = new CourseCatalog("慕课网课程主目录",1);
imoocMainCourseCatalog.add(linuxCourse);
imoocMainCourseCatalog.add(windowsCourse);
imoocMainCourseCatalog.add(javaCourseCatalog); imoocMainCourseCatalog.print(); }
}

输出效果:

类关系图如下图: 星号表示多个

3 相关模式

(1)组合模式和装饰模式

这两个模式可以组合使用。装饰模式在组装多个装饰器对象的时候,是一个装饰器找下一个装饰器,下一个再找下一个,如此递归下去。其实这种结构也可以使用组合模式来帮助构建,这样一来,装饰器对象就相当于组合模式的 Composite X对象了。要让两个模式能很好地组合使用,通常会让它们有一个公共的父类。因此装饰器必须支持组合模式需要的一些功能,比如,增加、删除子组件等。

(2)组合模式和享元模式

这两个模式可以组合使用。 如果组合模式中出现大量相似的组件对象的话,可以考虑使用享元模式来帮助级存组件对象,这样可以减少对内存的需要。使用享元模式也是有条件的,如果组件对象的可变化部分的状态能够从组件对象中分离出去,并且组件对象本身不需要向父组件发送请求的话,就可以采用享元模式。

(3)组合模式和迭代器模式

这两个模式可以组合使用。在组合模式中,通常可以使用迭代器模式来遍历组合对象的子对象集合,而无需关心具体存放子对象的聚合结构。

(4)组合模式和访问者模式

这两个模式可以组合使用。访问者模式能够在不修改原有对象结构的情况下,为对象结构中的对象增添新的功能。访问者模式和组合模式合用,可以把原本分教在 Composite和Laf类中的操作和行为都局部化。如果在使用组合模式的时候,预计到今后可能会有增添其他功能的可能,那么可以采用访问者模式,来预留好添加新功能的方式和通道,这样以后在添加新功能的时候,就不需要再修改已有的对象结构和已经实现的功能了。

(5)组合模式和职责链模式

这两个模式可以组合使用。职责链模式要解决的问题是:实现请求的发送者和接收者之间解耦。职责链模式的实现方式是把多个接收者组合起来,构成职责链,然后让请求在这条上传递,直到有接收者处理这个请求为止可以应用组合模式来构建这条链,相当于是子组件找父组件,父组件又找父组件,如此递归下去,构成一条处理请求的组件对象链。

(6)组合模式和命令模式

这两个模式可以组合使用。命令模式中有一个宏命令的功能,通常这个宏命令就是使用组合模式来组装出来的。

0

组合模式(Composite)---结构型的更多相关文章

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

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

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

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

  3. 合成模式(Composite)-结构型

    原理 合成模式属于对象的结构模式,有时又叫做“部分——整体”模式.合成模式将对象组织到树结构中,可以用来描述整体与部分的关系.合成模式可以使客户端将单纯元素与复合元素同等看待. 有时候又叫做部分-整体 ...

  4. Java设计模式14:常用设计模式之组合模式(结构型模式)

    http://blog.csdn.net/jason0539/article/details/22642281

  5. 设计模式 笔记 组合模式 Composite

    //---------------------------15/04/16---------------------------- //Composite 组合模式----对象结构型模式 /* 1:意 ...

  6. 组合模式/composite模式/对象结构型模式

    组合模式/composite模式/对象结构型 意图 将对象组合成树形结构以表示"整体--部分"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 动机 C ...

  7. 设计模式(七)组合模式Composite(结构型)

    设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 ...

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

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

  9. 【设计模式】组合模式 Composite Pattern

    树形结构是软件行业很常见的一种结构,几乎随处可见,  比如: HTML 页面中的DOM,产品的分类,通常一些应用或网站的菜单,Windows Form 中的控件继承关系,Android中的View继承 ...

  10. 设计模式系列之组合模式(Composite Pattern)——树形结构的处理

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

随机推荐

  1. docker login Harbor时报错403 Forbidden

    背景 在本地搭建了harbor后,在进行了相关配置后,还是报错:Error response from daemon: login attempt to http://10.xx.xx.xx:8000 ...

  2. 【LOJ】#3103. 「JSOI2019」节日庆典

    LOJ#3103. 「JSOI2019」节日庆典 能当最小位置的值一定是一个最小后缀,而有用的最小后缀不超过\(\log n\)个 为什么不超过\(\log n\)个,看了一下zsy的博客.. 假如\ ...

  3. SSM框架的整合与使用——实现简单的转账系统

    一.整合思路 SSM框架即SpringMVC + Spring + MyBati框架集,是一种轻量级的Web开源框架.它们各自在JAVA三层架构中负责的模块如下图所示: 其中,SpringMVC与Sp ...

  4. SVN常用命令--Mac端【转载】

    * 版本库布局 1. trunk主干 trunk就是开发的主线,一般项目都是导入到主线来开发的. 2. branches分支 branches一般是trunk某个版本的拷贝,如果你想在某一段时间单独对 ...

  5. Dijkstra算法——超~~详细!!

    Dijkstra算法_ ** 时隔多月,我又回来了!**_ 今天下午久违的又学了会儿算法,又重新学习了一遍Dijkstra,这是第三次重新学习Dijkstra(*以前学的都忘完了>_<*) ...

  6. 第十三章 ZYNQ-MIZ702 PL中断请求

    本篇文章主要介绍外设(PL)产生的中断请求,在PS端进行处理. 在PL端通过按键产生中断,PS接受到之后点亮相应的LED. 本文所使用的开发板是Miz702 PC 开发环境版本:Vivado 2015 ...

  7. Go入门所踩过的坑:cannot find package "" in any of

    问题:cannot find package "" in any of.现已按照博客解决,分享一种自己踩得坑欢迎大神指导交流! 首先使用go env查看当前环境变量,新手入门出现找 ...

  8. SIP协议入门:初学者必须明白的几个重要概念

    SIP协议初学者必须明白的几个重要概念 http://blog.sina.com.cn/s/blog_60e1d7bb0100f6er.html 一. SIP协议的分层结构 SIP是一个分层结构协议, ...

  9. LeetCode 腾讯精选50题--二叉树中的最大路径和

    二叉树中的最大路径和 题目描述 给定一个非空二叉树,返回器最大路径和,路径指一条从任意节点出发,到达任意节点的序列,该路径至少包含一个节点,且不一定经过根节点 解题思路 树这一类数据结构我还不是很熟悉 ...

  10. Div实现水平垂直居中

    在实际应用中很多地方不仅要求实现元素的水平居中或者垂直居中效果,还可能会在水平方向和垂直方向上都要实现居中效果,下面就简单介绍几种元素水平垂直居中的方法(注:不同的方法会存在一些优缺点以及兼容性问题) ...