迭代器模式
引子
迭代这个名词对于熟悉 Java 的人来说绝对不陌生。我们常常使用JDK 提供的迭代接口
进行java collection 的遍历:
Iterator it = list.iterator();
while(it.hasNext()){
//using “it.next();”do some businesss logic
}
而这就是关于迭代器模式应用很好的例子。
下面我们设想一下情景,一个电子商务平台,注册的所有用户都应该包括与之发生关系商品的属性(买入的商品,卖出的商品,仓库中的商品…),在实际中又可能因为某种原因,这些商品需要使用不同的集合存储,比如买入的商品用ArrayList,卖出的商品用Vector,仓库中的单品用数组,那么当我们想遍历这些具体商品时就需要分别对这几种集合遍历操作才可以实现,那么有没有什么模式可以解决这一弊端呢?------下面我们来看看迭代器模式。
角色
<!--[if !supportLists]-->1) <!--[endif]-->迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
我们就使用Java提供的迭代器接口
2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录
遍历中的当前位置。
因为 Vector,ArrayList都支持迭代器,所以我们这里只要给数据提供一个迭代器即可
import java.util.Iterator;
public class StoreIterator implements Iterator { Product[] products; int pos = 0;
public StoreIterator(Product[] products) { this.products = products; }
@Override public boolean hasNext() { // TODO Auto-generated method stub if (products != null) { if (pos < products.length) { return true; } } return false; }
@Override public Object next() { // TODO Auto-generated method stub if (products != null) { return products[pos++]; } return null; }
@Override public void remove() { // TODO Auto-generated method stub if (pos < 0) { System.out.print("异常"); } else { if (products[pos] != null) { for (int i = pos; i < products.length - 1; i++) { products[pos] = products[pos + 1]; } products[products.length - 1] = null; } } } } |
<!--[if !supportLists]-->3) <!--[endif]-->容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。
因为不论是卖出记录,买入记录,还是库存记录都属商品的记录,所以我们就抽象一个商品记录接口
import java.util.Iterator;
/** * 抽象容器 * @author Benson * */ public interface ProductRegister {
//返回迭代器 public Iterator createIterator(); } |
4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口
——这个具体迭代器角色于该容器的结构相关。
import java.util.ArrayList; import java.util.Iterator; import java.util.List;
/** * 具体容器类 * * @author Benson * */ public class BuyProductsRegister implements ProductRegister { List products = new ArrayList();
public BuyProductsRegister(){ Product p1=new Product("加湿器",255); Product p2=new Product("血压仪",322); products.add(p1); products.add(p2); }
@Override public Iterator createIterator() { // TODO Auto-generated method stub return products.iterator(); }
} |
import java.util.Iterator; import java.util.Vector;
/** * 具体容器类 * * @author Benson * */ public class SaleProductRegister implements ProductRegister {
Vector products = new Vector();
public SaleProductRegister() { Product p1 = new Product("VC", 35); Product p2 = new Product("MSN", 99); products.add(p1); products.add(p2); }
@Override public Iterator createIterator() { // TODO Auto-generated method stub return products.iterator(); } } |
import java.util.Iterator; import java.util.Vector;
/** * 具体容器类 * @author Benson * */ public class StoreProductRegister implements ProductRegister { Product[] products;
public StoreProductRegister() { Product p1 = new Product("XXX", 235); Product p2 = new Product("windows98", 199); products=new Product[2]; products[0]=p1; products[1]=p2; }
@Override public Iterator createIterator() { // TODO Auto-generated method stub return new StoreIterator(products); }
} |
调用
public class User {
String name;
public User(String name) {
this.name = name;
}
/**
* 打印所有商品
*
* @param iterator
*/
private void printProducts(Iterator iterator) {
if (iterator != null) {
while (iterator.hasNext()) {
Product p = (Product) iterator.next();
System.out.println(p.getName());
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
User u = new User("benson");
// 遍历用户所有有关产品
ProductRegister buy = new BuyProductsRegister(); //买入记录
ProductRegister sale = new SaleProductRegister(); //卖出记录
ProductRegister store = new StoreProductRegister(); //库存记录
u.printProducts(buy.createIterator());
u.printProducts(sale.createIterator());
u.printProducts(store.createIterator());
}
}
总结
public class User {
String name;
public User(String name) {
this.name = name;
}
/**
* 打印所有商品
*
* @param iterator
*/
private void printProducts(Iterator iterator) {
if (iterator != null) {
while (iterator.hasNext()) {
Product p = (Product) iterator.next();
System.out.println(p.getName());
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
User u = new User("benson");
// 遍历用户所有有关产品
ProductRegister buy = new BuyProductsRegister(); //买入记录
ProductRegister sale = new SaleProductRegister(); //卖出记录
ProductRegister store = new StoreProductRegister(); //库存记录
u.printProducts(buy.createIterator());
u.printProducts(sale.createIterator());
u.printProducts(store.createIterator());
}
}
迭代器模式的适用范围:
1) 访问一个容器对象的内容而无需暴露它的内部表示。
2) 为遍历不同的容器结构提供一个统一的接口(多态迭代)。
与组合模式结合