PHP设计模式之迭代器模式Iterator实例分析【对象行为型】


Posted in PHP onApril 26, 2020

本文实例讲述了PHP设计模式之迭代器模式Iterator。分享给大家供大家参考,具体如下:

1.概述

类中的面向对象编程封装应用逻辑。类,就是实例化的对象,每个单独的对象都有一个特定的身份和状态。单独的对象是一种组织代码的有用方法,但通常你会处理一组对象或者集合。

集合不一定是均一的。图形用户界面框架中的 Window 对象可以收集任意数量的控制对象 - Menu、Slider 和 Button。并且,集合的实现可以有多种方式:PHP 数字是一个集合,但也是一个散列表,一个链接列表,一个堆栈以及队列。

例子1:电视遥控器的频道遍历

PHP设计模式之迭代器模式Iterator实例分析【对象行为型】

2.问题

如何操纵任意的对象集合?

如一个列表(List)或者一个集合(Set),我们又如何提供一种方法来让别人可以访问它的元素,而又不需要暴露它的内部结构?

3.解决方案

迭代器模式:使用迭代器模式来提供对聚合对象的统一存取,即提供一个外部的迭代器来对聚合对象进行访问和遍历 , 而又不需暴露该对象的内部结构。又叫做游标(Cursor)模式 。

你可能没有意识到这一点,但你每天都在使用迭代器模式 。

如在PHP开发中,它潜藏在 PHP 的数组类型和各种数组操作函数中。(其实,给你一些固有类的数组的组合和一群用这些固有类工作的可变函数,你将不得不使用这些数组来处理对象集合。这是在 PHP 中的本地数组迭代:

$test = array(‘one', ‘two', ‘three');
$output = ‘'; reset($test); 
do {
$output .= current($test);
} while (next($test));
echo $output; // produces ‘onetwothree'

reset() 函数将迭代重新转到数组的开始;current() 返回当前元素的值;next() 则前进至数组中的下一个元素并返回新的 current() 值。当你超出数组的最后一个元素时,next() 返回 false。使用这些迭代方法,PHP 数组的内部实现就与你不相关了。

迭代器结合了封装和多态的面向对象程序设计原理。使用迭代器,你可以对集合中的对象进行操作,而无需专门了解集合如何显现或者集合包含什么(对象的种类)。迭代器提供了不同固定迭代实现的统一接口,它完全包含了如何操纵特定集合的详细信息,包括显示哪些项(过滤)及其显示顺序(排序)。

4.适用性

迭代器模式可用来:

• 访问一个聚合对象的内容而无需暴露它的内部表示。
• 需要为聚合对象提供多种遍历方式。
• 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)

5.结构

PHP设计模式之迭代器模式Iterator实例分析【对象行为型】

结构上可以看出,迭代器模式在客户与容器之间加入了迭代器角色。迭代器角色的加入,就可以很好的避免容器内部细节的暴露,而且也使得设计符号“单一职责原则”。

注意,在迭代器模式中,具体迭代器角色和具体容器角色是耦合在一起的——遍历算法是与容器的内部细节紧密相关的。为了使客户程序从与具体迭代器角色耦合的困境中脱离出来,避免具体迭代器角色的更换给客户程序带来的修改,迭代器模式抽象了具体迭代器角色,使得客户程序更具一般性和重用性。这被称为多态迭代

6.模式的组成

抽象迭代器(Iterator): 迭代器定义访问和遍历元素的接口。
具体迭代器(ConcreteIterator):  具体迭代器实现迭代器Iterator接口。对该聚合遍历时跟踪当前位置。
抽象聚合类(Aggregate): 聚合定义创建相应迭代器对象的接口。
具体聚合类(ConcreteAggregate): 体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。

7.效果

•迭代器模式的作用:

1 ) 它支持以不同的方式遍历一个聚合对象 : 复杂的聚合可用多种方式进行遍历。迭代器模式使得改变遍历算法变得很容易 : 仅需用一个不同的迭代器的实例代替原先的实例即可。你也可以自己定义迭代器的子类以支持新的遍历。
2) 迭代器简化了聚合的接口 有了迭代器的遍历接口,聚合本身就不再需要类似的遍历接口了。这样就简化了聚合的接口。
3) 在同一个聚合上可以有多个遍历 每个迭代器保持它自己的遍历状态。因此你可以同时进行多个遍历。
4)在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足“开闭原则”的要求。

迭代器模式的缺点

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

8.实现

我们直接实现spl的iterator:

<?php
 
/**
 * 具体迭代器(ConcreteIterator): 具体迭代器实现迭代器Iterator接口。对该聚合遍历时跟踪当前位置。
 */
class ConcreteIterator implements Iterator {
 protected $_key;
 protected $_collection;
 public function __construct($collection){
 $this->_collection = $collection;
 $this->_key = 0;
 }
 public function rewind(){
 $this->_key = 0;
 }
 public function valid(){
 
 return isset($this->_collection[$this->_key]);
 }
 public function key(){
 return $this->_key;
 }
 public function current(){
 return $this->_collection[$this->_key];
 }
 public function next(){
 return ++$this->_key;
 }
 
}
 
/**
 * 具体聚合类(ConcreteAggregate): 
 */
class ConcreteAggregate implements IteratorAggregate{
 protected $_arr;
 public function __construct($array){
 $this->_arr = $array;
 }
 
 public function getIterator(){
 return new  ConcreteIterator($this->_arr);
 }
}
 
$_collectionay = array(1,2,3,3,4);
$it = new ConcreteIterator($_collectionay);
foreach($it as $key=>$value){
 echo $key.':'.$value.'<br/>';
}

9.与其他相关模式

Composite :迭代器常被应用到象复合这样的递归结构上。
Factory Method:多态迭代器靠Factory Method来例化适当的迭代器子类。
Memento:常与迭代器模式一起使用。迭代器可使用一个 Memento来捕获一个迭代的状态。迭代器在其内部存储Memento。

10.总结与分析

1)聚合是一个管理和组织数据对象的数据结构。
2)聚合对象主要拥有两个职责:一是存储内部数据;二是遍历内部数据
3)存储数据是聚合对象最基本的职责。
4)将遍历聚合对象中数据的行为提取出来,封装到一个迭代器中,通过专门的迭代器来遍历聚合对象的内部数据,这就是迭代器模式的本质。迭代器模式是“单一职责原则”的完美体现。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php的一个登录的类 [推荐]
Mar 16 PHP
thinkphp3.0 模板中函数的使用
Nov 13 PHP
php实现的CSS更新类实例
Sep 22 PHP
php中$_POST与php://input的区别实例分析
Jan 07 PHP
typecho插件编写教程(四):插件挂载
May 28 PHP
php自定义扩展名获取函数示例
Dec 12 PHP
CI框架实现框架前后端分离的方法详解
Dec 30 PHP
thinkphp3.2实现在线留言提交验证码功能
Jul 19 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
Jun 16 PHP
实例解析php的数据类型
Oct 24 PHP
PHP实现字符串的全排列详解
Apr 24 PHP
laravel 实现用户登录注销并限制功能
Oct 24 PHP
Yii Framework框架开发微信公众平台示例
Apr 26 #PHP
PHP随机生成中文段落示例【测试网站内容时使用】
Apr 26 #PHP
PHP过滤器 filter_has_var() 函数用法实例分析
Apr 23 #PHP
PHP优化之批量操作MySQL实例分析
Apr 23 #PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
Apr 23 #PHP
Thinkphp 框架扩展之行为扩展原理与实现方法分析
Apr 23 #PHP
Thinkphp 框架扩展之标签库驱动原理与用法分析
Apr 23 #PHP
You might like
php下使用无限生命期Session的方法
2007/03/16 PHP
PHP的变量类型和作用域详解
2014/03/12 PHP
详解PHP中的Traits
2015/07/29 PHP
详解PHP数组赋值方法
2015/11/07 PHP
PHP实现的简单分页类及用法示例
2016/05/06 PHP
JavaScript高级程序设计阅读笔记(十六) javascript检测浏览器和操作系统-detect.js
2012/08/14 Javascript
javascript学习(一)构建自己的JS库
2013/01/02 Javascript
一些常用弹出窗口/拖放/异步文件上传等实用代码
2013/01/06 Javascript
JS动态修改图片的URL(src)的方法
2015/04/01 Javascript
NodeJS实现阿里大鱼短信通知发送
2016/01/17 NodeJs
AugularJS从入门到实践(必看篇)
2017/07/10 Javascript
vue2.0中vue-cli实现全选、单选计算总价格的实例代码
2017/07/18 Javascript
js使用html2canvas实现屏幕截取的示例代码
2017/08/28 Javascript
vue展示dicom文件医疗系统的实现代码
2018/08/27 Javascript
jQuery pagination分页示例详解
2018/10/23 jQuery
JS实现指定区域的全屏显示功能示例
2019/04/25 Javascript
浅谈layui 绑定form submit提交表单的注意事项
2019/10/25 Javascript
微信小程序之导航滑块视图容器功能的实现代码(简单两步)
2020/06/19 Javascript
使用Python的urllib和urllib2模块制作爬虫的实例教程
2016/01/20 Python
python 第三方库的安装及pip的使用详解
2017/05/11 Python
python Web开发你要理解的WSGI &amp; uwsgi详解
2018/08/01 Python
python爬虫学习笔记之pyquery模块基本用法详解
2020/04/09 Python
通过自学python能找到工作吗
2020/06/21 Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
2020/09/29 Python
Python的scikit-image模块实例讲解
2020/12/30 Python
Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)
2020/03/18 HTML / CSS
STAY JAPAN台湾:预订日本民宿
2018/07/22 全球购物
介绍一下UNIX启动过程
2013/11/14 面试题
高中生校园生活自我评价
2013/09/19 职场文书
医学专业五年以上个人求职信
2013/12/03 职场文书
高中生毕业自我鉴定范文
2013/12/22 职场文书
租赁协议书范本
2014/04/22 职场文书
检讨书1000字
2014/10/11 职场文书
2016七夕情人节感言
2015/12/09 职场文书
护士自荐信范文(2016推荐篇)
2016/01/28 职场文书
my.ini优化mysql数据库性能的十个参数(推荐)
2021/05/26 MySQL