Head First 设计模式--Iterator & Composite

Chapter 9 --迭代器模式和组合模式

                                   管理良好的集合

1. 迭代器模式依赖于一个名为迭代器的接口。

iterator interface

Structure

  • hasNext()方法告诉我们,是否在这个聚合中还有更多的元素。
  • next()方法返回这个聚合中的下一个对象。
  • remove()方法允许从聚合中删除由next()方法返回的最后一个项。

 

2. 当我们说“集合”(collection)的时候,我们指的是一群对象。其存储方式可以是各式各样的数据结构,例如:列表、数组、散列表,无论用什么方式存储,一律可以视为是集合,有时候也被称为聚合(aggregate)。

 

 

迭代器模式:

提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

 

iterator

Structure

  • Aggregate: 有一个共同的接口供所有的聚合使用,这对客户代码是很方便的;将客户代码从集合对象的实现解耦了。
  • ConcreteAggregate: 这个具体聚合持有一个对象的集合,并实现一个方法,利用此方法返回集合的迭代器。每一个具体聚合都要负责实例化一个具体迭代器,此迭代器能够遍历对象集合。
  • Iterator: 这是所有迭代器都必须实现的接口,它包含一些方法,利用这些方法可以在集合元素之间游走。
  • ConcreteIterator: 这个具体迭代器负责管理目前遍历的位置。

 

3. 迭代器模式把在元素之间游走的责任交给迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注在它所应该专注的事情上面(管理对象集合),而不必去理会遍历的事情。使得责任各得其所。

 

4. 对于外部迭代器,客户通过调用next()取得下一个元素。而内部的迭代器则是由迭代器自己控制。在这种情况下,因为客户无法控制遍历的过程,你必须将操作传入给迭代器,所以内部迭代器不如外部迭代器有弹性。



设计原则:

(1) 单一责任:一个类应该只有一个引起变化的原因。
类的每个责任都有改变的潜在区域。超过一个责任,意味着超过一个改变的区域。该原则告诉我们,尽量让每个类保持单一责任。

5. 当一个模块或一个类被设计成只支持一组相关的功能时,我们说它具有高内聚;反之,当被设计成支持一组不相关的功能时,则为低内聚。

6. Collection和Iterator的好处在于,每个Collection都知道如何创建自己的Iterator。只要调用ArrayList上的iterator(),就可以返回一个具体的Iterator,而你根本不需要知道或关心到底使用了哪个具体类,你只要使用它的Iterator接口就可以了。


组合模式:
允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。

Composite
Structure
  • Client: 客户使用Component接口操作组合中的对象。
  • Component: Component为组合中的所有对象定义一个接口,不管是组合还是叶节点。它也可以为add()、remove()、getChild()和它的操作实现一些默认的行为。
  • Leaf: 叶节点通过实现Composite支持的操作,定义了组合内元素的行为。叶节点没有孩子。叶节点也继承了add()、remove()和getChild()这样的方法,这些方法对叶节点或许没有意义。
  • Composite: Composite的角色是要定义组件的行为,而这样的组件具有子节点。Composite也实现了叶节点相关的操作。其中有一些操作可能对于Composite意义不大,因此在这种情况下可能产生异常。

7. 组合模式让我们能用树形方式创建对象的结构,树里面包含了组合以及个别的对象。使用组合结构,我们能把相同的操作应用在组合和个别对象上。也就是说,在大多数情况下,可以忽略对象组合和个别对象之间的差别。

8. 组合包含组件。组件有两种:组合与叶节点元素。听起来有点递归的味道。组合持有一群孩子,这些孩子可以是别的组合或者叶节点元素。但你用这种方式组织数据的时候,最终会得到树形结构(由上而下的树形结构),根部是一个组合,而组合的分支逐渐往下延伸,直到叶节点为止。

9. 组合模式以单一责任设计原则换取透明性(transparency)。即通过让组件的接口同时包含一些管理子节点和叶节点的操作,客户就可以将组合和叶节点一视同仁,一个元素究竟是组合还是叶节点,对客户是透明的。

10. 组合迭代器是一个外部迭代器,它必须维护它在遍历中的位置,以便外部客户可以通过调用hasNext()和next()来驱动遍历。我们的代码必须维护组合递归结构的位置,通常使用堆栈来维护这些位置信息。

11. 空迭代器:该迭代器的hasNext()永远返回false。

12. 我们称包含其他组件的组件为组合对象,而称没有包含其他组件的为叶节点对象。

13. 如果某个组合结构很复杂,或者遍历的代价太高,那么实现组合节点的缓存就很有帮助。比方说,如果你要不断地遍历一个组合,而且它的每一个子节点都需要进行某些计算,那么你就应该使用缓存来临时保存结果,省去遍历的开支。


本章小结:
  • 迭代器允许访问聚合的元素,而不需要暴露它的内部结构。
  • 迭代器将遍历聚合的工作封装进一个对象中。
  • 当使用迭代器的时候,我们依赖聚合提供遍历。
  • 迭代器提供了一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。
  • 我们应该努力让一个类只分配一个责任。
  • 组合模式提供一个结构,可同时包容个别对象和组合对象。
  • 组合模式允许客户对个别对象以及组合对象一视同仁。
  • 组合结构内的任意对象称为组件,组件可以是组合,也可以是叶节点。
  • 在实现组合模式时,有许多设计上的折衷。你要根据需要平衡透明性和安全性。

猜你喜欢

转载自eriol.iteye.com/blog/1074340
今日推荐