设计模式学习笔记--迭代(Iterator)模式

写在模式学习之前

什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式;每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案;当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。

设计模式就是抽象出来的东西,它不是学出来的,是用出来的;或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以“模式专家”的角度来看,都是最佳的设计,不得不说是“最佳的模式实践”,这是因为你积累了很多的实践经验,知道“在什么场合代码应该怎么写”,这本身就是设计模式。

有人说:“水平没到,学也白学,水平到了,无师自通”。诚然,模式背熟,依然可能写不出好代码,更别说设计出好框架;OOP理解及实践经验到达一定水平,同时也意味着总结了很多好的设计经验,但"无师自通",却也未必尽然,或者可以说,恰恰是在水平和经验的基础上,到了该系统的学习一下“模式”的时候了,学习一下专家总结的结果,印证一下自己的不足,对于提高水平还是很有帮助的。

本系列的设计模式学习笔记,实际是对于《Java与模式》这本书的学习记录。

迭代模式的定义

首先要说,关于迭代模式,是和Java中的聚集密切相关的。体现的是“开-闭”原则,强调的是封装变化的思想。

迭代器是在JDK2-5时代的聚集遍历模式,从JKD5开始,对聚集的遍历,推崇for(E e:Es)的形式,更少的变量,更不易出错,迭代器是有点过时了,所以我们学习迭代模式,是为了开阔一下视野,理解其思想。

迭代模式是为了解决两类问题:

1、迭代逻辑没有改变,但是需要从一种聚集变成另一种聚集,如果不同的聚集有不同的遍历接口方式,那么客户端就需要修改代码了,所以。。。

2、迭代逻辑改变了,比如只需要遍历>1的元素,这个时候就需要修改聚集中原来的遍历方法,或者提供新的方法,这不符合“开-闭”原则,也就是没有“把不变的结构(聚集)从系统中抽象出来,把可变的结构(各种条件的遍历)封装起来”,对于这种思想,Java是这样实现的,伪代码如下:

public class Aggregation
{
	public Iterator<E> iterator() {
        return new Itr();
    }

    public ListIterator<E> listIterator() {
        return new ListItr(0);
    }

    //迭代子类
	private class Itr implements java.util.Iterator<E>
	{
		...
	}

	//迭代子类
	private class ListItr implements java.util.ListIterator<E>
	{
		...
	}
}

迭代模式的定义:

迭代模式,又叫游标模式,是对象的行为模式。迭代模式可以顺序的访问一个聚集中的元素而不必暴漏聚集的内部对象。

迭代模式的结构

结构图

所涉及的角色

(1)抽象迭代(Iterator)角色:定义遍历元素所需的接口

(2)具体迭代(ConcreteIterator)角色:实现了Iterator接口,并保持迭代过程中的游标位置

(3)聚集(Aggregate)角色:这个角色会给出创建迭代对象的接口

(4)具体聚集(ConcreteAggregate)角色:实现了创建迭代对象的接口,并返回一个合适的具体迭代对象

(5)客户端(Client)角色:持有对聚集及其迭代对象的引用,调用迭代对象的迭代接口,也有可能通过迭代对象操作聚集元素的增加和删除

代码实现

import java.util.Vector;

public class IteratorTest {

	public static void main(String[] args)
	{
		System.out.println("正向迭代演示");
		Purchase a = new PurchaseOfCopyA();
		a.add("one");a.add("tow");a.add("three");
		Iterator ia = a.createIterator();
		ia.first();
		while(!ia.isLast())
		{
			System.out.println("a: " + ia.current());
			ia.next();
		}

		System.out.println("逆向迭代演示");
		Purchase b = new PurchaseOfCopyB();
		b.add("one");b.add("tow");b.add("three");
		Iterator ib = b.createIterator();
		ib.first();
		while(!ib.isLast())
		{
			System.out.println("b: " + ib.current());
			ib.next();
		}
	}
}

/**
 * 抽象聚集类
 *
 */

@SuppressWarnings(value={"rawtypes","unchecked"})
abstract class Purchase
{

	private Vector elements = new Vector(5);

	//工厂方法模式,提供迭代对象的实现
	public abstract Iterator createIterator();	

	public void add(Object o)
	{
		elements.add(o);
	}

	public void remove(Object o)
	{
		elements.remove(o);
	}

	public Object currentItem(int index)
	{
		return elements.elementAt(index);
	}

	public int count()
	{
		return elements.size();
	}
}

/**
 * 具体聚集类:警察A
 *
 */
class PurchaseOfCopyA extends Purchase
{

	@Override
	public Iterator createIterator() {
		return new ForwardIterator(this);
	}
}

/**
 * 具体聚集类:警察B
 *
 */
class PurchaseOfCopyB extends Purchase
{

	@Override
	public Iterator createIterator() {
		return new BackIterator(this);
	}
}

/**
 * 抽象迭代角色
 *
 */
interface Iterator
{
	void first();	//移到第一个元素
	void next();	//移到下一个元素
	boolean isLast();	//是否最后一个元素
	Object current();	//当前的元素
}

/**
 * 正向迭代
 *
 */
class ForwardIterator implements Iterator
{
	private int index;
	private Purchase obj;

	public ForwardIterator(Purchase obj)
	{
		this.obj = obj;
	}

	@Override
	public void first() {
		index = 0;
	}

	@Override
	public void next() {
		if(!isLast())
		{
			index++;
		}
	}

	@Override
	public boolean isLast() {
		if(index > obj.count()-1) return true;
		return false;
	}

	@Override
	public Object current() {
		return obj.currentItem(index);
	}
}

/**
 * 逆向迭代
 *
 */
class BackIterator implements Iterator
{
	private int index;
	private Purchase obj;

	public BackIterator(Purchase obj)
	{
		this.obj = obj;
	}

	@Override
	public void first() {
		index = obj.count()-1;
	}

	@Override
	public void next() {
		if(!isLast())
		{
			index--;
		}
	}

	@Override
	public boolean isLast() {
		if(index < 0) return true;
		return false;
	}

	@Override
	public Object current() {
		return obj.currentItem(index);
	}
}

迭代模式优缺点

优点:

(1)符合“开-闭”原则,封装变化,不论是聚集对象变化,或者迭代规则变化,都不会影响到客户端的代码;

(2)每个聚集对象可以有一个以上的迭代对象,彼此独立。因此一个聚集可以同时有几个迭代在进行之中;

缺点:

(1)迭代必须以一定线性顺序进行,聚集并不一定是线性的,比如Hash,所以使用迭代可能导致客户端误会,误认为聚集是线性的;

(2)迭代给出的聚集元素没有类型特征,一般都是Object,因此需要客户端具备这些元素类型的知识。

时间: 2024-12-27 09:52:58

设计模式学习笔记--迭代(Iterator)模式的相关文章

设计模式学习笔记--访问者(Visitor)模式

写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式. 设计模式就是抽象出来的东西,它不是学出来的,是用出来的:或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以"模式专家"的角度来看,都是最佳的设计,不得不说是"最佳的模式实践",这

设计模式学习笔记--备忘录(Mamento)模式

写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式. 设计模式就是抽象出来的东西,它不是学出来的,是用出来的:或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以"模式专家"的角度来看,都是最佳的设计,不得不说是"最佳的模式实践",这

设计模式学习笔记--状态(State)模式

写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式. 设计模式就是抽象出来的东西,它不是学出来的,是用出来的:或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以"模式专家"的角度来看,都是最佳的设计,不得不说是"最佳的模式实践",这

设计模式学习笔记--工厂方法模式

学习过简单工厂模式,感觉很好用.在创建对象时,可以将复杂的初始化操作从客户端分离出来,简化客户端代码.大大的减少了代码修改的难度.而且可以通过参数不同,创建不同的对象. 但是简单工厂模式也有一些弊端,违背了开放--封闭原则.即如果我们增加了一个产品,对应的工厂也要进行修改,即switch---case中要新增加一些分支条件,不利于扩展.所以就有了下面的工厂方法模式: 工厂方法模式:定义了一个用于创建对象的接口,子类决定实例化哪一个类,工厂方法模式使一个类的实例化延迟到子类. // 设计模式Dem

[大话设计模式]学习笔记——简单工厂模式

序 说好的每天进步一点点的,结果工作太忙,一直在加班,都没有学习新东西.我还要进BAT呢. 坚持每天学习新东西. 写代码时,意识到在代码结构上还是有点欠缺.赶紧补上. 纪录对设计模式的认识.小菜变大鸟.进攻BAT. 应用场景: 编写一个计算器控制台程序,要求输入两个数和运算符号,得到结果. 这本书使用C#写的.已有博主用JAVA写出来,参考:http://blog.csdn.net/ghsau/article/details/8163418 常见的做法: 写一个方法封装计算机的功能,我们只需传参

设计模式学习笔记之命令模式

命令模式 将“请求”封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 说明: 1.命令模式将发出请求的对象和执行请求的对象解耦: 2.在被解耦的两者之间是通过命令对象进行沟通的.命令对象封装了接受者和一个或一组动作: 3.调用者通过调用命令对象的execute()发出请求,这会使得接受者的动作被调用: 4.调用者可以接受命令当做参数,甚至在运行时动态地进行: 5.命令可以支持撤销,做法事实现一个undo()方法来回到exexcute()被执行前的状态:

设计模式学习笔记--简单工厂模式

背景: 在开发过程中,经常会创建大量的对象,创建对象后还会涉及到一系列的初始化操作,而我们也不一定会只是在创建对象之后马上就使用对象,而且如果初始化操作很复杂,代码看起来就会非常杂乱,如果有变动,所有的初始化操作都要进行修改,相当难以维护. 功能: 将对象的创建和使用分离开来,专门用于创建对象并初始化.并且进行扩展后,可以根据参数不同,创建不同的对象. 例子: // 设计模式Demo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ

设计模式学习笔记-创建型模式总结

一.总结 创建型模式抽象了实例化的过程:它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象 创建型模式将实例化委托给另一个对象. 在这些模式中有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在 一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以及何时创建这些方面给予 了我们很大的灵活性.它们允许

设计模式学习笔记之组合模式

组合模式 允许你将对象组合成树形结构来表现“整体/部分”层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 使用组合结构,我们能把相同的操作应用在组合和个别对象上.换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别. 说明: 1.组合模式使添加或者删除子节点变得容易: 场景: 1.想要标识对象的部分-整体结构: 2.想要客户端忽略组合对象和个体对象的差异,客户端将统一使用组合结构中的所有对象: /** * 为组合中所有对象定义一个接口,不管是组合还是节点 * */ pu