设计模式——迭代器模式

提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。C#和PHP自己已经实现了这个模式,例如C#里边的foreach方法。当我们要访问一个聚集而又不需要知道它内部结构的时候,可以考虑用迭代器模式,迭代器模式遍历是由它内部提供的方法实现的。

迭代器模式有四个角色:

迭代器:迭代器定义访问和遍历元素的接口

具体迭代:具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置

聚合:聚合定义创建相应迭代器对象的接口(可选)

具体聚合:具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例(可选)

意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

主要解决:不同的方式来遍历整个整合对象。

何时使用:遍历一个聚合对象。

如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。

优点: 1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

使用场景: 1、访问一个聚合对象的内容而无须暴露它的内部表示。 2、需要为聚合对象提供多种遍历方式。 3、为遍历不同的聚合结构提供一个统一的接口。

注意事项:迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

由于PHP自己有Iterator这个了,所以本次代码只做演示,只可意会,不要使用。先来一个不用聚合的:

<?php
//抽象迭代器 由于Iterator是关键字所有用MyIterator
abstract class MyIterator{
	//第一个
	abstract function First();
	//下一个  
    abstract function Next();
    //是否是最后一个  
    abstract function IsDone();
    //当前对象  
    abstract function CurrentItem();  
}

//具体的迭代器--不带聚集的
class ConcreteIterator extends MyIterator{
	private $Aggregate;
	private $Current = 0;
    function __construct(Array $Aggregate)
    {
    	$this->Aggregate = $Aggregate;
    }
    function First()
    {
    	return $this->Aggregate[0];
    }
    function Next()
    {
    	$this->Current++;
    	if($this->Current<count($this->Aggregate))
    	{
    	    return $this->Aggregate[$this->Current];	
    	}
    	else
        {
    	    return null;	
    	}    	
    }
    function IsDone()
    {    	
    	return $this->Current>=count($this->Aggregate)?true:false;
    }
    function CurrentItem()
    {
    	return $this->Aggregate[$this->Current];
    }
}

//调用

$Testarray = array('a','b','c');
$ConcreteIterator = new ConcreteIterator($Testarray);
while (!$ConcreteIterator->IsDone())
{	
	echo $ConcreteIterator->CurrentItem()." it's your turn.";
	$ConcreteIterator->Next();
}
?>

上边这个,没有用到聚集,下边这段代码用到了聚集:

<?php
//抽象迭代器 由于Iterator是关键字所有用MyIterator
abstract class MyIterator{
	//第一个
	abstract function First();
	//下一个  
    abstract function Next();
    //是否是最后一个  
    abstract function IsDone();
    //当前对象  
    abstract function CurrentItem();  
}

//抽象聚合
abstract class Aggregate  {
	abstract function CreateIterator();
}

//具体的迭代器
class ConcreteIterator extends MyIterator{
	private $Aggregate;
	private $Current = 0;
    function __construct(ConcreteAggregate $Aggregate)
    {
    	$this->Aggregate = $Aggregate;
    }
    function First()
    {
    	return $this->Aggregate->Aggregates[0];
    }
    function Next()
    {
    	$this->Current++;
    	if($this->Current<$this->Aggregate->Count())
    	{
    	    return $this->Aggregate->Aggregates[$this->Current];	
    	}
    	else
        {
    	    return null;	
    	}    	
    }
    function IsDone()
    {    	
    	return $this->Current>=$this->Aggregate->Count()?true:false;
    }
    function CurrentItem()
    {
    	return $this->Aggregate->Aggregates[$this->Current];
    }
}

//具体的聚合
class ConcreteAggregate extends Aggregate{
	public  $Aggregates = array();
	public function CreateIterator()
	{
		return new ConcreteIterator($this);
	}
	
	//返回聚集总个数
	public function Count()
	{
		return count($this->Aggregates);
	}
}

//测试类
class Test{
	public $Name;
	function __construct($Name)
	{
		$this->Name = $Name;
	}
	public function GetName()
	{
		echo $this->Name;
	}
}

//调用
$TestA = new Test("DaLi");
$TestB = new Test("ErGou");

$ConcreteAggregate = new ConcreteAggregate();
$ConcreteAggregate->Aggregates = array($TestA,$TestB);
$ConcreteIterator = $ConcreteAggregate->CreateIterator();
while (!$ConcreteIterator->IsDone())
{	
	echo $ConcreteIterator->CurrentItem()->GetName()." it's your turn.";
	$ConcreteIterator->Next();
}
?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值