设计模式初探-迭代器模式

2014-11-24 02:55:45 · 作者: · 浏览: 0

迭代器模式(ITERATOR),又称游标(Cursor),提供了一种方法,用于顺序访问一个聚合对象中的各个元素,而不需暴露该对象的内部表示,属于对象行为型模式。迭代器模式通过将对聚合对象(通常为列表)的访问和遍历从聚合对象中分离出来并放入一个迭代器对象中,迭代器对象知道如何遍历列表,这样不仅可以简化聚合对象的实现(将遍历操作交给迭代器负责,自己只负责保存),还可以以不同的方式遍历列表。

一、使用场景

1、访问一个聚合对象的内容而无需暴露它的内部表示。

2、支持对聚合对象的多种遍历,比如正向遍历,逆向遍历,JDK的迭代器只实现正向遍历。

3、为遍历不同的聚合结构提供一个统一的接口。对不同的聚合结构只需切换要遍历的对象而不需改变遍历过程的代码。

二、UML图

迭代器模式

三、Java实现

package study.patterns.iterator;

import java.util.ArrayList;
import java.util.List;
/**
 * 迭代器模式,为遍历聚合结构而生! 
 * 迭代器模式通常使用工厂方法模式来实例化适当的迭代器子类。
 * @author qbg
 */
public class IteratorPattern {
	public static void main(String[] args) {
		List
  
    list = new ArrayList
   
    (); list.add("Java
    编程思想"); list.add("设计模式"); list.add("编程匠艺"); list.add("重构"); AbstractList
    
      books = new ConcreteList
     
      (list); Iterator
      
        iterator = books.iterator(); System.out.println("=======正向遍历==========="); while(iterator.hasNext()){ System.out.print(iterator.next()+","); } System.out.println("\n=======逆向遍历==========="); while(iterator.hasPrevious()){ System.out.print(iterator.previous()+","); } } } /** * 抽象聚合类 * @param 
       
         */ abstract class AbstractList
        
         { protected List
         
           elements = new ArrayList
          
           (); public AbstractList(List
           
             eles){ this.elements = eles; } public void add(E e){ elements.add(e); } public void remove(E e){ elements.remove(e); } public List
            
              getAll(){ return elements; } /** * 声明创建迭代器对象的抽象工厂方法 */ public abstract Iterator
             
               iterator(); } /** * 具体聚合类,创建基于该聚合类的迭代器 * @param 
              
                */ class ConcreteList
               
                 extends AbstractList
                
                 { public ConcreteList(List
                 
                   eles) { super(eles); } @Override public Iterator
                  
                    iterator() { return new ConcreteIterator
                   
                    (this); } } /** * 遍历器抽象接口,支持泛型 */ interface Iterator
                    
                     { /** * 正向遍历,判断是否有后继节点 */ public boolean hasNext(); /** * 游标下移,返回游标越过的元素引用 */ public E next(); /** * 逆向遍历,判断是否有前驱节点 */ public boolean hasPrevious(); /** * 游标上移,返回游标越过的元素引用 */ public E previous(); } /** * 具体迭代器,用于遍历AbstractList
                     
                      集合. * 支持正向遍历和逆向遍历 * @param 
                      
                        */ class ConcreteIterator
                       
                         implements Iterator
                        
                         { private AbstractList
                         
                           list;//要遍历的集合 private List
                          
                            elements;//集合中的元素 private int cursor_forword;//正向遍历的游标,用于记录正向遍历的位置 private int cursor_backword;//逆向遍历的游标,用于记录逆向遍历的位置 public ConcreteIterator(AbstractList
                           
                             list){ this.list = list; this.elements = this.list.getAll();//获取集合元素 this.cursor_forword = 0;//设置正向遍历游标初始值 this.cursor_backword = elements.size()-1;//设置逆向遍历游标初始值 } @Override public boolean hasNext() { return cursor_forword < elements.size(); } @Override public E next() { E e = elements.get(cursor_forword); cursor_forword++; return e; } @Override public boolean hasPrevious() { return cursor_backword >= 0; } @Override public E previous() { E e = elements.get(cursor_backword); cursor_backword--; return e; } } 
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  
运行结果:

=======正向遍历===========
Java编程思想,设计模式,编程匠艺,重构,
=======逆向遍历===========
重构,编程匠艺,设计模式,Java编程思想,

四、模式优缺点

优点:

1、支持以不同的方式遍历一个聚合。想改变遍历方式只需用一个不同的迭代器实例代替原先的实例即可。

2、迭代器简化聚合的接口。有了迭代器的遍历接口,聚合本身就不需要类似的遍历接口了。

3、在同一个聚合上可以有多个遍历。每个迭代器保持它自己的遍历状态,互不影响。

缺点:

1、抽象迭代器的设计比较难以把握,如果前期设计不好,后期改动就会非常大。比如JDK的迭代器只支持正向遍历,如果想实现其他遍历方式只能通过添加辅助类实现。