第十九章、组合模式

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

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. android 虚拟设备的用法
  2. 汇编语言随笔(9)-实验11(用条件转移指令来编写子程序)
  3. 完成AOP 顶层设计-CglibAopProxy
  4. Jquery基础知识
  5. replicated vs global mode - 每天5分钟玩转 Docker 容器(105)
  6. 准备一些万圣节的乐趣——UI设计素材模板
  7. Tomcat8+redis实现session共享
  8. C# IndexOf用法
  9. android+祖玛游戏源码,祖玛游戏源代码
  10. 糖友控糖是在控什么糖呢
  11. 优秀孩子的父母都有这五个特点
  12. 结合RocketMQ 源码,带你了解并发编程的三大神器
  13. 推荐下 刘慈欣的《科学中的故事资源》
  14. python glob.glob使用
  15. java-通知-阿里云短信服务
  16. find()的基本使用
  17. 如何判断牛市是否来了,看这4种指标就够了
  18. python结合ogr2ogr之地理数据格式转换-2
  19. CHAPTER 18 Semantic Role Labeling
  20. ASP 3.0高级编程(七)

热门文章

  1. 磁盘上有一个黄色的感叹号和小锁
  2. Unity iOS混合开发
  3. 数学--数学分类及相关网站和软件
  4. AMiner 会议论文推荐第十一期
  5. 排序 归并排序_56
  6. 2021年更快乐的40件事
  7. 用Photoshop软件制作法线图以及查看效果细节
  8. PHP业务中发短信功能
  9. php cgi启动失败,无法启动phpcgi
  10. 等价关系、等价类与划分