一、组合模式定义

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

如上图所示(截取自《Head First Design Patterns》一书),主要包括三个部分:

1. Component抽象组件。定义参加组合对象的共有方法和属性,可以定义一些默认的函数或属性。

2. Leaf叶子节点。构成组合树的最小构建单元。

3. Composite树枝节点组件。它的作用是组合树枝节点和叶子节点形成一个树形结构。

Component : 组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理 Component 的子部件。

 1 abstract class Component {
 2     protected String name;
 3
 4     public Component(String name) {
 5         this.name = name;
 6     }
 7
 8     public abstract void Add(Component c);
 9     public abstract void Remove(Component c);
10     public abstract void Display(int depth);
11 }

Leaf : 表示叶节点对象。叶子节点没有子节点。

 1 class Leaf extends Component {
 2
 3     public Leaf(String name) {
 4         super(name);
 5     }
 6
 7     @Override
 8     public void Add(Component c) {
 9         System.out.println("Can not add to a leaf");
10     }
11
12     @Override
13     public void Remove(Component c) {
14         System.out.println("Can not remove from a leaf");
15     }
16
17     @Override
18     public void Display(int depth) {
19         String temp = "";
20         for (int i = 0; i < depth; i++)
21             temp += '-';
22         System.out.println(temp + name);
23     }
24
25 }

Composite : 定义枝节点行为,用来存储子部件,在 Component 接口中实现与子部件相关的操作。例如 Add 和 Remove。

 1 class Composite extends Component {
 2
 3     private List<Component> children = new ArrayList<Component>();
 4
 5     public Composite(String name) {
 6         super(name);
 7     }
 8
 9     @Override
10     public void Add(Component c) {
11         children.add(c);
12     }
13
14     @Override
15     public void Remove(Component c) {
16         children.remove(c);
17     }
18
19     @Override
20     public void Display(int depth) {
21         String temp = "";
22         for (int i = 0; i < depth; i++)
23             temp += '-';
24         System.out.println(temp + name);
25
26         for (Component c : children) {
27             c.Display(depth + 2);
28         }
29     }
30
31 }

Client : 通过 Component 接口操作结构中的对象。

 1 public class CompositePattern {
 2
 3 public static void main(String[] args) {
 4     Composite root = new Composite("root");
 5     root.Add(new Leaf("Leaf A"));
 6     root.Add(new Leaf("Leaf B"));
 7
 8     Composite compX = new Composite("Composite X");
 9     compX.Add(new Leaf("Leaf XA"));
10     compX.Add(new Leaf("Leaf XB"));
11     root.Add(compX);
12
13     Composite compXY = new Composite("Composite XY");
14     compXY.Add(new Leaf("Leaf XYA"));
15     compXY.Add(new Leaf("Leaf XYB"));
16     compX.Add(compXY);
17
18     root.Display(1);
19 }
20
21 }

二、组合模式优势

  节点自由扩展增加。使用组合模式,如果想增加一个树枝节点或者叶子节点都是很简单的,只要找到它的父节点就可以了,非常容易扩展,符合“开闭原则”。应用最广的模式之一。应用在维护和展示部分-整体关系的场景,如树形菜单、文件夹管理等等。一棵树形结构的所有节点都是Component,局部和整体对调用者来说都是一样的,没有区别,所以高层模块不比关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。

  1、可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易。

2、客户端调用简单,客户端可以一致的使用组合结构或其中单个对象。

3、定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构。

4、更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码。

组合模式的缺点: 使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。

使用场景:

    1、需要表示一个对象整体或部分层次,在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待它们。

2、让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节。

三、组合模式在Android源码中的应用

在Android源码中,都能找到使用组合模式的例子,其中在《Android源码学习之观察者模式应用》介绍到的ViewGroup和View的结构就是一个组合模式,结构图如下所示:

现在来看看它们是如何利用组合模式组织在一起的,首先在View类定义了有关具体操作,然后在ViewGroup类中继承View类,并添加相关的增加、删除和查找孩子View节点,代码如下:

/** @attr ref android.R.styleable#ViewGroup_clipChildren * @attr ref android.R.styleable#ViewGroup_clipToPadding * @attr ref android.R.styleable#ViewGroup_layoutAnimation * @attr ref android.R.styleable#ViewGroup_animationCache * @attr ref android.R.styleable#ViewGroup_persistentDrawingCache * @attr ref android.R.styleable#ViewGroup_alwaysDrawnWithCache * @attr ref android.R.styleable#ViewGroup_addStatesFromChildren * @attr ref android.R.styleable#ViewGroup_descendantFocusability * @attr ref android.R.styleable#ViewGroup_animateLayoutChanges */ public abstract class ViewGroup extends View implements ViewParent, ViewManager {

接着看增加孩子节点函数:

  /*** Adds a child view. If no layout parameters are already set on the child, the* default parameters for this ViewGroup are set on the child.** @param child the child view to add** @see #generateDefaultLayoutParams()*/public void addView(View child) { addView(child, -1); } /** * Adds a child view. If no layout parameters are already set on the child, the * default parameters for this ViewGroup are set on the child. * * @param child the child view to add * @param index the position at which to add the child * * @see #generateDefaultLayoutParams() */ public void addView(View child, int index) { LayoutParams params = child.getLayoutParams(); if (params == null) { params = generateDefaultLayoutParams(); if (params == null) { throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null"); } } addView(child, index, params); } /** * Adds a child view with this ViewGroup's default layout parameters and the * specified width and height. * * @param child the child view to add */ public void addView(View child, int width, int height) { final LayoutParams params = generateDefaultLayoutParams(); params.width = width; params.height = height; addView(child, -1, params); } /** * Adds a child view with the specified layout parameters. * * @param child the child view to add * @param params the layout parameters to set on the child */ public void addView(View child, LayoutParams params) { addView(child, -1, params); } /** * Adds a child view with the specified layout parameters. * * @param child the child view to add * @param index the position at which to add the child * @param params the layout parameters to set on the child */ public void addView(View child, int index, LayoutParams params) { if (DBG) { System.out.println(this 

转载于:https://www.cnblogs.com/linghu-java/p/5728308.html

设计模式11---组合模式(Composite Pattern)相关推荐

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

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

  2. python 设计模式之组合模式Composite Pattern

    #引入一 文件夹对我们来说很熟悉,文件夹里面可以包含文件夹,也可以包含文件. 那么文件夹是个容器,文件夹里面的文件夹也是个容器,文件夹里面的文件是对象. 这是一个树形结构 咱们生活工作中常用的一种结构 ...

  3. 如何让孩子爱上设计模式 ——11.外观模式(Facade Pattern)

    如何让孩子爱上设计模式 --11.外观模式(Facade Pattern) 标签: 设计模式初涉 场景引入 相信各位玩过LOL英雄联盟游戏的童鞋,对下面两个英雄都不会陌生吧:       分别是瑞雯和 ...

  4. C#设计模式——组合模式(Composite Pattern)

    一.概述 在软件开发中,我们往往会遇上类似树形结构的对象体系.即某一对象既可能在树形结构中作为叶节点存在,也可能作为分支节点存在.比如在文件系统中,文件是作为叶节点存在,而文件夹就是分支节点.在设计这 ...

  5. 设计模式:组合模式(Composite Pattern)

    组合模式: 又叫部分整体模式, 它创建了对象组的树形结构,将对象组合成树状结构以表示"整体-部分"的层次关系. JDK中的HashMap就使用了组合模式 public abstra ...

  6. 设计模式之组合模式(Composite)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  7. 24组合模式(Composite Pattern)

    动机(Motivate):     组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元 ...

  8. 组合模式(Composite Pattern)

    组合模式概述 定义:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构.组合模式让客户端可以统一对待单个对象和组合对象.又被成为"部分-整体"(Part-Whole)模式, ...

  9. [设计模式] 8 组合模式 Composite

    DP书上给出的定义:将对象组合成树形结构以表示"部分-整体"的层次结构.组合使得用户对单个对象和组合对象的使用具有一致性.注意两个字"树形".这种树形结构在现实 ...

  10. 研磨设计模式 之 组合模式(Composite) 3——跟着cc学设计系列

    15.3  模式讲解 15.3.1  认识组合模式 (1)组合模式的目的 组合模式的目的是:让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作. 实现这个目标的关键之处,是设计一 ...

最新文章

  1. JS中Base64的编码与解码
  2. 根据HTML5 获取当前位置的经纬度【百度地图】【高德地图】
  3. PWN-PRACTICE-BUUCTF-25
  4. STM32的串口通信
  5. Redis数据存储解决方案
  6. 自定义圆形进度条ProgressBar
  7. 小米随身wifi驱动linux驱动下载,小米随身WIFI驱动|小米WIFI驱动官方最新版(支持Win10)...
  8. 分布形态的度量-偏度系数与峰度系数的探讨
  9. 英国留学生Discursive Essay怎么写?
  10. 利用谷歌搜索建立自己的站内搜索引擎
  11. 集成googlepay,出现Service not registered
  12. 华东师大计算机全国排名,华东师范大学就这水平进的985?
  13. Lesson 43 Smart 组件 vs Dumb 组件
  14. SpringBoot接口数据加解密实战
  15. DNS服务器未响应是什么意思
  16. echarts柱形图+折线图混合案例
  17. Revit二次开发2、RevitAPI、RevitAPIUI及Revit开发三大利器
  18. c++并发编程实战 第一章
  19. Linux高级查询命令
  20. rpcs3模拟器配置要求是什么?

热门文章

  1. 【CodeForces - 988C 】Equal Sums (思维,STLmap,STLset,tricks)
  2. npm安装与卸载和cordova及ionic项目打包调试等相关命令总结归纳
  3. 镇江 linux技术支持,东云镇江服务器
  4. 撞球编程c语言,急!C语言编程题——撞球
  5. linux虚拟机上安装域名,虚拟机如何安装linux系统
  6. java循环左一_左旋转字符串(Java)-循环Index方式
  7. leetcode155. 最小栈
  8. 每天定时打开某个网页_Python科普帖定时通知
  9. Ubuntu环境下,使用clion编译器,使用开源opensll的对称AES算法对于文件进行加密,C++代码
  10. C语言二维数组 int arr[2][3]