第十九章、组合模式

组合模式也称为部分-整体模式,结构型设计模式之一。

1.定义

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

2.使用场景

(1)表示对象的部分-整体层次结构时。

(2)从一个整体中能够独立出部分模块或功能的场景。

3.UML类图

(1)Component:抽象根节点,为组合中的对象声明接口。在适当的情况下,实现所有类共有接口的缺省行为。声明一个接口用于访问和管理Component的子节点。可在递归结构中定义一个接口,用于访问一个父节点,并在合适的情况下实现它。

(2)Composite:定义有子节点的那些枝干节点行为,存储子节点,在Component接口中实现与子节点有关的操作。

(3)Leaf:在组合中表示叶子节点对象,叶子节点没有子节点,在组合中定义节点对象的行为。

(4)Client:通过Component接口操纵组合节点的对象。

如图这种将组合所使用的方法全部定义在抽象类的方式称为透明的组合模式,如果将Component中的Add、Remove、GetChild去除,只在Composite中单独添加,这种方式称为安全的组合模式。然而后者违背了依赖倒置原则。

4.简单实现

以文件和文件夹这样的文件系统为例

文件和文件夹的抽象类:(Component)

public abstract class Dir {/*** 声明一个List成员变量来储存文件夹下的所有元素*/protected List<Dir> dirs = new ArrayList<Dir>();private String name; //当前文件或文件夹名public Dir(String name) {this.name = name;}/*** 添加一个文件或文件夹* * @param dir 文件或文件夹*/public abstract void addDir(Dir dir);/*** 移除一个文件或文件夹* * @param dir 文件或文件夹*/public abstract void rmDir(Dir dir);/*** 清空文件夹下所有元素*/public abstract void clear();/*** 输出文件夹目录结构*/public abstract void print();/*** 获取文件夹下所有的文件或文件夹* * @return 文件夹下所有的文件或文件夹*/public abstract List<Dir> getFiles();/*** 获取文件或文件夹名* * @return 文件或文件夹名*/public String getName(){return name;}
}

表示文件夹的类:(Composite)

public class Folder extends Dir{public Folder(String name) {super(name);}@Overridepublic void addDir(Dir dir) {dirs.add(dir);}@Overridepublic void rmDir(Dir dir) {dirs.remove(dir);}@Overridepublic void clear() {dirs.clear();}@Overridepublic void print() {System.out.print(getName() + "(");Iterator<Dir> iter = dirs.iterator();while (iter.hasNext()) {Dir dir = iter.next();dir.print();if(iter.hasNext()){System.out.print(", ");}}System.out.print(")");}@Overridepublic List<Dir> getFiles() {return dirs;}}

表示文件夹的类:(Leaf)

public class File extends Dir{public File(String name) {super(name);}@Overridepublic void addDir(Dir dir) {throw new UnsupportedOperationException("文件对象不支持该操作!");}@Overridepublic void rmDir(Dir dir) {throw new UnsupportedOperationException("文件对象不支持该操作!");}@Overridepublic void clear() {throw new UnsupportedOperationException("文件对象不支持该操作!");}@Overridepublic void print() {System.out.print(getName());}@Overridepublic List<Dir> getFiles() {throw new UnsupportedOperationException("文件对象不支持该操作!");}}

客户类:

public class Client {public static void main(String[] args) {//构造一个目录对象表示C盘根目录Dir diskC = new Folder("C");//C盘根目录下有一个文件Log.txtdiskC.addDir(new File("Log.txt"));//C盘根目录下有三个目录Windows、PerfLogs、Program FileDir dirWin = new Folder("Windows");//Windows目录下有文件explorer.exedirWin.addDir(new File("explorer.exe"));diskC.addDir(dirWin);//PerfLogs目录Dir dirPer = new Folder("PerfLogs");//PerfLogs目录下有文件null.txtdirPer.addDir(new File("null.txt"));diskC.addDir(dirPer);//Program File目录Dir dirPro = new Folder("Program File");//Program File目录下有文件ftp.txtdirPro.addDir(new File("ftp.txt"));diskC.addDir(dirPro);//打印出文件结构diskC.print();}
}

结果:

C(Log.txt, Windows(explorer.exe), PerfLogs(null.txt), Program File(ftp.txt))

5.Android源码中的模式实现

1.View和ViewGroup的嵌套组合

View和ViewGroup的结构很像上面的UML类图,不过View的视图层级使用的是安全的组合模式。ViewGroup有对View的addView、removeView、getChildAt等方法,想必大家也很熟悉。

6.总结

1.优点

(1)组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,他让高层模块忽略了层次的差异,方便对整个层次结构进行控制。

(2)简化了高层模块的代码。

(3)在组合模式中增加新的枝干构件和叶子构件都很方便,无须对现有类库进行修改,符合“开闭原则”。

(4)对树形结构的控制变得简单。

2.缺点

组合模式不容易限制组合中的构件。因为大多数情况下,它们都来自于相同的抽象层,此时,必须进行类型检查来实现,这个实现过程较为复杂。

《Android源码设计模式解析与实战》读书笔记(十九)相关推荐

  1. 《Android源码设计模式解析与实战》读书笔记(十三)

    第十三章.备忘录模式 备忘录模式是一种行为模式,该模式用于保存对象当前的状态,并且在之后可以再次恢复到此状态,有点像是我们平常说的"后悔药". 1.定义 在不破坏封闭的前提下,捕获 ...

  2. 《Android源码设计模式解析与实战》读书笔记(十七)

    第十七章.中介者模式 中介者模式也称为调解者模式或调停者模式,是一种行为型模式. 1.定义 中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用.从而使它们可以松散耦合.当某些对象之 ...

  3. 《Android源码设计模式解析与实战》读书笔记(十二)

    第十二章.观察者模式 观察者模式是一个使用率非常高的模式,它最常用在GUI系统.订阅–发布系统.因为这个模式的一个重要作用就是解耦,将被观察者和观察者解耦,使得它们之间的依赖性更小,甚至做到毫无依赖. ...

  4. 《Android源码设计模式解析与实战》读书笔记(十四)

    第十四章.迭代器模式 迭代器模式,又叫做游标模式,是行为型设计模式之一.我们知道对容器对象的访问必然会涉及遍历算法,我们可以将遍历的方法封装在容器中,或者不提供遍历方法,让使用容器的人自己去实现去吧. ...

  5. 《Android源码设计模式解析与实战》读书笔记(十)

    第十章.解释器模式 解释器模式是一种用的比较少的行为型模式,其提供了一种解释语言的语法或表达式的方式.但是它的使用场景确实很广泛,只是因为我们自己很少回去构造一个语言的文法,所以使用较少. 1.定义 ...

  6. 《Android源码设计模式解析与实战》读书笔记(二十四)

    第二十四章.桥接模式 桥接模式也称为桥梁模式,是结构型设计模式之一.桥接模式中体现了"单一职责原则"."开闭原则"."里氏替换原则".&qu ...

  7. 《Android源码设计模式解析与实战》读书笔记(二十一)

    第二十一章.装饰模式 装饰模式也称为包装模式,是结构型设计模式之一.装饰模式是一种用于替代继承技术的一种方案. 1.定义 动态的给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵 ...

  8. 《Android源码设计模式解析与实战》读书笔记(十一)

    第十一章.命令模式 命令模式是行为型模式之一.总体来说并不难理解,只是比较繁琐,他会将简单的调用关系解耦成多个部分,增加类的复杂度,但是即便如此,命令模式的结构依然清晰. 1.定义 将一个请求封装成一 ...

  9. 《Android源码设计模式解析与实战》读书笔记(十六)

    第十六章.访问者模式 访问者模式是一种行为型模式,它是23种设计模式中最复杂的一个,虽然使用频率不高,但是并不代表可以忽略,在合适的地方,它会带来意想不到的灵活性.访问者模式,顾名思义使用了这个模式后 ...

最新文章

  1. BZOJ 1003[ZJOI2006]物流运输(SPFA+DP)
  2. python电脑下载什么软件好-Python工具 | 4个好用的开源 Python 下载器
  3. 8 reasons why SPIR-V makes a big difference
  4. OpenGL开发之旅基础知识介绍
  5. tp5 database.php,Tp5项目修改数据库
  6. python在线编辑器可视化_python软件——wxpython可视化编辑器 v4.1附使用教程
  7. spring-data-elasticsearch (elasticsearch 6.7.0) @Document 和 @Field 注解详解
  8. python模拟鼠标拖动滑块_Python中selenium的作用链模拟滑块运动,python,ActionChains,移动...
  9. 魔力岛服务器稳定吗,魔力岛《飘渺仙剑》寻找GM你愉我乐线上活动
  10. C语言 字符‘0‘和‘\0‘ 以及整数0的区别
  11. 章文嵩坐镇淘宝双11流量作战室
  12. sqrt函数实现(涉及3D游戏引擎源码)
  13. PPT乱码如何解决?
  14. Linux安装CentOS系统
  15. 揭示win32 api拦截细节
  16. xpath常见错误:Opening and ending tag mismatch: meta line 4 的处理方法【Python爬虫】
  17. Compiler - 编译器
  18. 台式计算机无法开机原因,台式电脑无法启动的原因和解决方法_电脑不能启动的原因与解决方法...
  19. uniapp vue页面嵌套webview组件 ,自定义webview大小
  20. 基于 Sodor 的矩阵乘法加速器设计之C++

热门文章

  1. 助力全球抗疫:3D突发公共卫生事件管理平台
  2. Windows临界区
  3. gradle全局代理
  4. 网络带宽与实际网速的区别-小常识
  5. 英语习语集锦::recommended::
  6. linux usermod命令
  7. IT职场人,切不要一辈子靠技术生存
  8. 23华北水利水电大学择校分析
  9. 测试工程师之Python面试题(附答案)
  10. Javascript高性能WebGL图表--LightningChart JS