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. redis主从复制初识

    一.作用 slave会通过被复制同步master上面的数据,形成数据副本 当master节点宕机时,slave可以升级为master节点承担写操作. 允许有一主多从,slave可以承担读操作,提高读性 ...

  2. ES使用小结之索引Rollover

    Elasticsearch 使用小结之索引Rollover 索引名 一般而言,客户端将数据每天写入一个索引,比如直接写入YYYY-MM-HH格式的索引,那么我们只需要在写入的客户端里面获取时间,然后得 ...

  3. DP单调队列--斜率优化P3195

    题意:https://www.luogu.com.cn/problem/P3195 思路:https://www.luogu.com.cn/problemnew/solution/P3195 #def ...

  4. python+selenium+webdriver+BeautifulSoup实现自动登录

    from selenium import webdriverimport timefrom bs4 import BeautifulSoupfrom urllib import requestimpo ...

  5. Python 基础(十六)--随机数模块

    random随机数模块 random.randint(1,10):随机1-10包括10 random.randrange(1,10,2):在1.3.5.7.9中随机,类似切片,不包括10 random ...

  6. Django ORM相关的一些操作

    一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 ...

  7. Asp.net core 学习笔记 QR code and Barcode

    QR code 和 Barcode 经常会使用到. Java 阵营有著名的 zxing https://github.com/zxing/zxing .Net 有对接它的 port https://g ...

  8. 浅谈hashcode

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  9. python+django学习三

    在这个网站看https://sshwsfc.github.io/xadmin/     xadmin结果一堆的坑,文档找不到界面,dome登陆就报错permission denied for rela ...

  10. 关于postgres数据库部署之后,发现不能被外机连接解决办法

    数据库 部署完毕之后,用其他机器的navcat连接发现不能连接,如下报错信息 于是在数据库服务器上查询是否启动正常,端口是否正常,发现都没有问题,由于之前也遇到了mysql部署之后,不能被其他机器访问 ...