行为型模式---迭代器模式

迭代器模式(Iterator Pattern)

   在软件开发时,经常需要使用聚合对象来存储一系列数据,聚合对象拥有两个职责:

   一是存储数据;二是遍历数据,前者是聚合对象的基本职责,而后者既是可变化的又是可分离的,因此可将遍历数据的行为从聚合对象中分离出来,封装在一个迭代器对象中;这可简化聚合对象的设计,符合单一职责的原则.
1. 定义: 提供一种方法来访问聚合对象,而不用暴露这个对象的内部表示;
2. 迭代器模式中的角色
    1) Iterator(抽象迭代器): 定义了访问和遍历元素的接口,声明了用于遍历数据元素的方法
    2) ConcreteIterator(具体迭代器): 实现了抽象迭代器接口,完成了对聚合对象的遍历,通过游标来记录在聚合对象中所处的当前位置,在具体实现时,游标通常是一个表示位置的非负整数;
    3) Aggregate(抽象聚合类): 它用于存储和管理元素对象,声明一个createIterator()方法用于创建一个迭代器对象,充当抽象迭代器工厂角色
    4) ConcreteAggregate(具体聚合类): 实现抽象聚合类声明的createIterator()方法,该方法返回一个与该具体聚合类对应的具体迭代器实例
    

若需要增加一个新的聚合类,并提供不同于商品数据聚合类的正向遍历和逆向遍历操作,只需增加一哥新的聚合子类和一个新的具体迭代器类即可,源代码无须修改,符合开闭原则

3. 案例

   1) 解决方案

   2) 代码实现

package com.zach.pattern.iterator;
/***
 *抽象迭代器接口
 * @author Zach
 *
 */
public interface AbstractIterator {
	
	public void next();   //移至下一个元素
	
	public boolean isLast();  //判断是否为最后一个元素
	
	public void previous();   //移至上一个元素
	
	public boolean isFirst();  //判断是否为第一个元素
	
	public Object getNextItem();  //获取下一个元素
	
	public Object getPreviousItem();   //获取上一个元素
}

package com.zach.pattern.iterator;

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

/**
 * 抽象聚合类
 * @author Zach
 *
 */
public abstract class AbstractObjectList {
	protected List<Object> list = new ArrayList<>();

	public AbstractObjectList(List<Object> list) {
		super();
		this.list = list;
	}
	
	public  void addObject(Object obj) {
		this.list.add(obj);
	}
	
	public  void removeObject(Object obj) {
		this.list.remove(obj);
	}
	
	public  List<Object> getObjects() {
		return this.list;
	}
	
	//声明抽象迭代器对象的工厂方法
	public abstract AbstractIterator createrator();
	
}

package com.zach.pattern.iterator;

import java.util.List;

/**
 * 抽象迭代器
 * @author Zach
 *
 */
public class ProductIterator implements AbstractIterator {
	
	private ProductList productList;  //维持对一个具体聚合类的引用
	
	private List<Object> products;
	
	private int cursor1; //定义一个游标,用于记录正向遍历的位置
	
	private int cursor2;  //定义一个逆向的游标,记录逆向遍历的位置
	
	
	public ProductIterator(ProductList list) {
		this.productList = list;
		this.products = list.getObjects();
		cursor1 = 0;
		cursor2 = products.size()-1;
	}
	

	@Override
	public void next() {
		if(cursor1<products.size()) {
			cursor1++;
		}
	}

	@Override
	public boolean isLast() {
		
		return (cursor1==products.size());
	}

	@Override
	public void previous() {
		if(cursor2>-1){
			cursor2--;
		}

	}

	@Override
	public boolean isFirst() {
		// TODO Auto-generated method stub
		return (cursor2==-1);
	}

	@Override
	public Object getNextItem() {
		// TODO Auto-generated method stub
		return products.get(cursor1);
	}

	@Override
	public Object getPreviousItem() {
		
		return products.get(cursor2);
	}

}

package com.zach.pattern.iterator;

import java.util.List;
/**
 * 具体聚合类
 * @author Zach
 *
 */
public class ProductList extends AbstractObjectList {

	public ProductList(List<Object> list) {
		super(list);
		// TODO Auto-generated constructor stub
	}

	@Override
	public AbstractIterator createrator() {
		// TODO Auto-generated method stub
		return new ProductIterator(this);
	}

}

package com.zach.pattern.iterator;

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

/**
 * 客户端
 * @author Zach
 *
 */
public class Client {
	
	public static void main(String[] args) {
		List<Object> products = new ArrayList<Object>();
		products.add("倚天剑");
		products.add("屠龙刀");
		products.add("断肠草");
		products.add("葵花宝典");
		products.add("易经经");
		
		//创建聚合对象
		AbstractObjectList list = new ProductList(products);
		//创建迭代器对象
		AbstractIterator iterator = list.createrator();
		
		System.out.println("正向遍历: ");
		while(!iterator.isLast()) {
			System.out.println(iterator.getNextItem());
			iterator.next();
		}
		
		System.out.println("===========================");
		
		System.out.println("逆向遍历: ");
		while(!iterator.isFirst()){
			System.out.println(iterator.getPreviousItem());
			iterator.previous();
			
		}
	}
}

运行结果
正向遍历: 
倚天剑
屠龙刀
断肠草
葵花宝典
易经经
===========================
逆向遍历: 
易经经
葵花宝典
断肠草
屠龙刀
倚天剑

若需要为ProductList类更换一个迭代器,只需要增加一个新的迭代器类子类即可;但如果要在迭代器中增加新的方法,则需要修改抽象迭代器源代码,这将违背开闭原则;

4. 使用内部类实现迭代器

   在迭代器的模式图中,具体迭代器和具体聚合类之间存在双重关系,在具体迭代器中需要维持一个对具体聚合对象的引用,该关联关系的目的是以便迭代器能够对这些数据进行遍历操作;除了使用关联关系,还可以将迭代器类设计为聚合类的内部类,达到遍历聚合对象的数据的目的,JDK中迭代器类就是通过这种方式实现的

5. 迭代器模式总结

1. 主要优点:
            1) 支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式,只需更换不同的迭代器即可
            2) 简化了聚合类
        
        2. 主要缺点:
            1) 增加新的聚合类需要对应增加新的迭代器类,类的个数会成对增加,增加了系统的复杂性
            2) 迭代器设计难度大,需要充分考虑系统将来的扩展
            
            
        3. 使用场景
            1) 访问一个聚合对象的内容而无须暴露它的内部实现表示
            2) 需要为一个聚合对象提供多种遍历方式
            3) 为遍历不同的聚合结构提供统一的接口

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值