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如何编写易读的代码
Jul 10 PHP
关于php循环跳出的问题
Jul 01 PHP
国产PHP开发框架myqee新手快速入门教程
Jul 14 PHP
PHP文件上传判断file是否己选择上传文件的方法
Nov 10 PHP
PHP的pcntl多进程用法实例
Mar 19 PHP
CentOS 上搭建 PHP7 开发测试环境
Feb 26 PHP
PHP错误处理函数register_shutdown_function使用示例
Jul 03 PHP
php+jQuery实现的三级导航栏下拉菜单显示效果
Aug 10 PHP
PHP实现动态创建XML文档的方法
Mar 30 PHP
php 字符串中是否包含指定字符串的多种方法
Apr 12 PHP
thinkphp5.1 文件引入路径问题及注意事项
Jun 13 PHP
PHP模版引擎原理、定义与用法实例
Mar 29 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使用mysql_query查询超大结果集超内存问题
2016/03/14 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
php实现的生成迷宫与迷宫寻址算法完整实例
2017/11/06 PHP
php读取本地json文件的实例
2018/03/07 PHP
laravel 实现向公共模板中传值 (view composer)
2019/10/22 PHP
js CSS操作方法集合
2008/10/31 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
js实现仿MSN带关闭功能的右下角弹窗代码
2015/09/04 Javascript
同步文本框内容JS代码实现
2016/08/04 Javascript
谈谈对JavaScript原生拖放的深入理解
2016/09/20 Javascript
JavaScript创建对象的七种方式全面总结
2017/08/21 Javascript
原生js实现移动端触摸轮播的示例代码
2017/12/22 Javascript
详解如何在vue项目中引入elementUI组件
2018/02/11 Javascript
Angular搜索场景中使用rxjs的操作符处理思路
2018/05/30 Javascript
typescript nodejs 依赖注入实现方法代码详解
2019/07/21 NodeJs
Python类的基础入门知识
2008/11/24 Python
python机器学习实战之最近邻kNN分类器
2017/12/20 Python
Win10 安装PyCharm2019.1.1(图文教程)
2019/09/29 Python
python3.7+selenium模拟淘宝登录功能的实现
2020/05/26 Python
Python如何截图保存的三种方法(小结)
2020/09/01 Python
详解Python利用configparser对配置文件进行读写操作
2020/11/03 Python
详解tf.device()指定tensorflow运行的GPU或CPU设备实现
2021/02/20 Python
CSS3地图动态实例代码(圆圈向外扩散)
2018/06/15 HTML / CSS
HTML5 Canvas旋转动画的2个代码例子(一个旋转的太极图效果)
2014/04/10 HTML / CSS
英国鲜花速递:Serenata Flowers
2018/04/03 全球购物
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
印尼最大的网上书店:Gramedia.com
2018/09/13 全球购物
幼儿园教师个人反思
2014/01/30 职场文书
优秀高中生事迹材料
2014/02/11 职场文书
《春笋》教学反思
2014/04/15 职场文书
Nginx设置日志打印post请求参数的方法
2021/03/31 Servers
html实现弹窗的实例
2021/06/09 HTML / CSS
浅析CSS在DevTools 中架构演变
2021/10/05 HTML / CSS
《黑岩★★射手 DAWN FALL》BD发售宣传CM公开
2022/04/04 日漫
Mybatis-Plus 使用 @TableField 自动填充日期
2022/04/26 Java/Android