您的位置:首页 > 编程语言 > Java开发

设计模式(9)--迭代器与组合模式

2014-05-23 16:52 375 查看
(1)散列表(hashtable)         共迭代器获取 hashtable.values().iterator();  因为每一笔数据都是由键值对组成。

(2)迭代器是用来遍历集合的。 Java5后集合都出了自己的遍历方式 如增加for循环。           遍历 也称 游走。。。

(3)数组:Array 长定固定   集合:ArrayList 可扩展,取数据不需要转型 

(4)Java中有自己的迭代器接口。在java.util.Iterator  . 

(5)集合:collection 也可称为聚合(aggregate)。其存储方式可以是各种各样的数据结构,例如:列表 ,数组,散列表,

 (6)collection 中的  如 ArrayList.iterator() 方式即可实现迭代器   hashtable.value().iterator() 。 

(7)但数组不能通过 .iterator 的方式实现迭代器。 所以可以自定义迭代器。

单一责任:  设计原则: 一个类应该只有一个引起变化的原因 。如果一个类管理某种聚合,又负责遍历,则就有两种责任了。

内聚(cohesion):它用来度量一个类或模块紧密地达到单一目的或责任。

(1) 当一个模块或个类被设计成只支持一组相关的功能时,我们说它具有高内聚,返之,当被设计成支持一组不相关的功能时,我们说它具有低内聚。

(2)内聚是一个比单一责任原则更普遍的概念。两者关系密切。遵守这个原则的类容易具有高内聚。容易维护。

迭代器模式(Iterator Pattern):

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

例:现在有两个菜单,一个是数组,一个是ArrayList  。它俩的遍历方式不一样。 所以现在可以通过迭代器 封装遍历。

(-- 创建迭代器接口--)

(--创建一个菜单迭代器--) 此迭代器需要一个菜单数组做为参数

(--菜单中有一个createIteraor方法 返回一个菜单迭代器--)菜单中有菜单数组做为参数 给菜单迭代器。 然后利用菜单迭代器遍历菜单即可。

(--因为菜单中菜单数组做为参数 所以 Objectnext() 方法返回的是菜单中的菜单项--)

//定义迭代器接口
public interface Iterator{
booleanhasNext();
Objectnext();
}
//实现一个具体的迭代器 (数组菜单的)
public class DinerMenuIterator implements Iterator{ //实现迭代器接口
MenuItem[] items ;
int position =0;  //当前数组遍历的位置
public DinerMenuIterator(MenuItem[] items){
this.items = items;   //传入一个菜单项的数组当做参数
}

public Objectnext(){
MenuItem menuItem = items[position];
position = position+1;
return menuItem;
}
public booleanhasNext(){
if(position>=items.length || items[position]==null){
return false;
 }else{
          return true;          //hasNext()方法会检查我们是否已经取得数组的所有的元素。如果还有元素待遍历。,则返回true.
 }
}

}
<pre name="code" class="java">// 利用迭代器改写菜单
public class DinerMenu{
static final int MAX_ITEMS = 6;  //菜单中有6个菜
int numberOfItems = 0;
MenuItem[] menuitems;           //菜单项 组成的数组
//构造器
//addItem()
public Iterator createIterator(){
reuturn new DinerMenuIterator(menuItems);   返回一个菜单迭代器
//返回迭代器接口。客户不知道 菜单是如何维护菜单项的,也不需要知道迭代器是如何迭现的。只需要利用这个迭代器遍历菜单即可。
}
</pre><pre name="code" class="java">  //利用迭代器遍历菜单
private void printMenu(Iterator iterator){     //菜单创建出来的菜单迭代器 <span style="color:#ff0000;">会引用菜单中的菜单数组作为参数</span>
while(iterator.hasNext()){
<span style="white-space:pre">	</span> MenuItem menuItem = (MenuItem)iterator.next();
}
}
//数组菜单 的createIterator()方法 返回一个自定义的 菜单迭代器
//<span style="color:#ff0000;">Arraylist 的菜单 createItertor()方法 可以直接 调用 .iterator()方法返回 一个菜单迭代器</span>。



上面是自定义迭代器。 可以使用java中的迭代器 java.util.Iterator 接口。
interface Iterator{
hasNext()
next()
remove()  //
}
如果不提供 remove() 功能 则可以抛出运行时异常 。java.lang.UnsupportedOperationException。


ArrayList 有一个返回代器的iterator()方法  。ArrayList 并不需要实现自忆的迭代器
</pre><pre name="code" class="java">问: 在多线程下,可能会有多个迭代器引用同一个对象聚合。 remove()会造成怎样的影响?
答: 后果并没有指明 。当多线程使用迭代器时,必须特别小心。





迭代器模式让我们能游走于聚合内的每一人元素,而又不暴露其内部的表示

把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所

Java中有一个Enumeration(枚举)接口,  java.util.Enumeration 是一个有序的迭代器实现。 

它有两个方法: hasMoreElements() 和 nextElement()。

你应该比较想用迭代器,而不是枚举。因为大多数的java类支持迭代器。

如果想把两者互想转换。 可以用适配器。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 java