设计模式学习十三:迭代器模式

一.概念

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

二.UML

  1. Aggregate(集合对象抽象类)。
  2. ConcreteAggregate(聚合对象具体类)。里面必然有某种数据结构,能增删改查所持有的对象。
  3. Iterator(迭代器抽象类)。对外提供顺序访问聚合对象中对象的方法。
  4. ConcreteIterator(具体迭代器类)。

 

三.实例分析

 

     Aggregate

package com.zzy.iterator;

/**
 * 聚合对象抽象类
 * @author eason
 *
 * @param <E>
 */
public interface Aggregate<E> {
	
	public Iterator<E> createIterator();

}

     ArrayAggregate

package com.zzy.iterator;

/**
 * 聚合对象抽象类,用一个数组来反映聚合对象
 * @author eason
 *
 * @param <E>
 */
public class ArrayAggregate<E> implements Aggregate<E> {
	
	private Object[] objs;
	
	public ArrayAggregate(Object[] objs) {
		this.objs = objs;
	}

	public Iterator<E> createIterator() {
		return new ArrayIterator<E>(objs);
	}

}

     ListAggregate

package com.zzy.iterator;

import java.util.List;

/**
 * 聚合对象抽象类,用一个List来反映聚合对象
 * @author eason
 *
 * @param <E>
 */
public class ListAggregate<E> implements Aggregate<E> {
	
	private List<E> lists;
	
	public ListAggregate(List<E> lists) {
		this.lists = lists;
	}

	public Iterator<E> createIterator() {
		return new ListIterator<E>(lists);
	}

}

     Iterator

package com.zzy.iterator;

/**
 * 迭代器接口
 * @author eason
 *
 * @param <E>
 */
public interface Iterator<E> {
	
	public boolean hasNext();
	
	public E next();
	
}

     ArrayIterator

package com.zzy.iterator;

/**
 * 数组型迭代器
 * @author eason
 *
 * @param <E>
 */
public class ArrayIterator<E> implements Iterator<E> {
	
	private Object[] obj;
	int position;

	public ArrayIterator(Object[] obj) {
		this.obj = obj;
	}

	@Override
	public boolean hasNext() {
		if(obj != null && position < obj.length) {
			return true;
		}
		return false;
	}

	public E next() {
		return (E) obj[position++];
	}

}

     ListIterator

package com.zzy.iterator;

import java.util.List;

/**
 * List型迭代器
 * @author eason
 *
 * @param <E>
 */
public class ListIterator<E> implements Iterator<E> {
	
	private List<E> lists;
	int current;

	public ListIterator(List<E> lists) {
		this.lists = lists;
	}

	@Override
	public boolean hasNext() {
		if(current < lists.size()) {
			return true;
		}
		return false;
	}

	@Override
	public E next() {
		return lists.get(current++);
	}

}

     TestIterator

package com.zzy.iterator;

import java.util.ArrayList;
import java.util.List;

/**
 * 测试类
 * @author eason
 *
 */
public class TestIterator {

	static String[] arrays = {"O1", "O2", "O3"};
	static List<String> lists = new ArrayList<String>();
	static {
		lists.add("L1");
		lists.add("L2");
		lists.add("L3");
	}
	
	public static void main(String[] args) {
		
		Iterator<String> arrayIterator = new ArrayAggregate<String>(arrays).createIterator();
		Iterator<String> listIterator = new ListAggregate<String>(lists).createIterator();
		
		printIterator(arrayIterator);
		printIterator(listIterator);
	}
	
	private static void printIterator(Iterator iterator) {
		while(iterator.hasNext()) {
			System.out.println(iterator.next());
		}
	}

}
  1. 现在有两个聚合对象:ArrayAggregate(内部用数组来保存对象),ArrayAggregate(内部用List来保存对象)。
  2. 现在client想访问这两聚合对象里面的对象,会分别循环Array和List来得到结果。因为Array和List这两个数据结构本身的区别,client要分别循环Array和List。
  3. 这个时候,我们考虑:将“分别循环”这个操作封装在一个迭代器接口里面;并为ArrayAggregate和ArrayAggregate提供一个来得到自身迭代器的方法createIterator();并提供具体的迭代器实现类,这个就是我们要完成的部分了。
  4. 此时,client拿到一个聚合类,就可以得到其迭代器,从而可以得到聚合对象中的对象了。client完完全全可以不知道迭代器是怎么迭代聚合对象的。

四.使用场景及使用感受

  1. 迭代器模式那元素之间游走的责任从聚合对象交到了迭代器。这让聚合对象代码更加简单,让聚合对象可以更加专注在它应该专注的事情上(管理聚合对象)。
  2. 我们经常使用的for-each遍历,其本质是对聚合对象进行迭代。java为我们提供了迭代器类java.util.Iterator。
  3. 设计原则:单一责任。一个类应该只有一个引起变化的原因。通俗点就是一个类只做一件事情。
  4. 内聚:要来度量一个类或者模块紧密地达到一个目的或责任。当一个类或模块被设计成只支持一组相关的的功能时,我们说它具有高内聚;反正,低内聚。

猜你喜欢

转载自zy19982004.iteye.com/blog/1440030