当前位置: 首页 > 后端技术 > PHP

PHP设计模式之迭代器模式

时间:2023-03-29 20:49:16 PHP

说到这种模式,就不得不提到循环语句。在《大话设计模式》中,作者表示这个模型的学习意义大于实际意义。为什么是这样?当然是foreach做的。任何语言都有这样一种相似的语法,可以轻松快速地遍历数组和对象,以至于迭代器模式逐渐成为23大设计模式中的明星过客。尤其是我们的PHP语言,PHP的强项在于对数组的灵活操作,它本身就是一个hashmap结构,自然会有各种方便的数组操作语法,而foreach也是我们最常用的语句,甚至比for还常用用过的。Gof类图及解释GoF定义:提供一种方法,在不暴露对象内部表示的情况下,顺序访问聚合对象中的每个元素CreateIterator(){$list=["a","b","c","d",];返回新的具体迭代器($列表);}}首先,它是一个聚合类,可以迭代Class,这里因为我是面向对象的设计模式,迭代器模式是针对迭代一个类的内容。这里,其实我们只是模拟了一个数组,交给了迭代器。接口MyIterator{公共函数First();公共功能下一个();公共功能IsDone();publicfunctionCurrentItem();}classConcreteIteratorimplementsMyIterator{private$list;私人索引;公共函数__construct($list){$this->list=$list;$this->index=0;}publicfunctionFirst(){$this->index=0;}publicfunctionNext(){$this->index++;}publicfunctionIsDone(){return$this->index>=count($this->list);}publicfunctionCurrentItem(){return$this->list[$this->index];}}迭代器出场,主要实现了对集合数据进行操作的四个方法。有点像你在学习数据结构或数据库时对游标所做的事情。使用First()和Next()移动光标,使用CurrentItem()获取当前光标的数据内容,使用IsDone()确认是否有下一条数据。因此,这种模式也称为游标模式。$agreegate=newConcreteAggregate();$iterator=$agreegate->CreateIterator();while(!$iterator->IsDone()){echo$iterator->CurrentItem(),PHP_EOL;$迭代器->下一步();}客户端可以直接使用while来操作。大家一定很好奇,为什么我们的迭代器接口类不命名为Iterator呢?试一试你就知道PHP已经为我们准备好了这个接口。实现之后就可以使用foreach来使用这个实现了Iterator接口的类。是不是很棒?最后我们来看看这个类的使用。类遍历不好吗?为什么要来回传递数组?开发过Java的同学一定知道,在一个名为Object类的JavaBean中,会写入一个List类型的变量,比如ListmyList,用来表示当前对象的集合。在使用过程中向这个List添加数据后,下次可以直接使用Object.myList获取一组数据。比如从接口获取到的json数组的内容可以通过这种方式存储到一个bean中。这时候我们就可以使用迭代器只对自己对象内部的数组进行操作了!以上Java内容其实是笔者在做Android开发时经常用到的。有时候数据库的JavaBean也会有这种数组来存放外键。但在PHP中很少使用,因为PHP中的大部分AR对象与Java中的Bean概念略有不同。有兴趣的同学可以了解一下!我们的手机厂是不可思议的。我们自己组装了一条生产线。这条生产线的主要用途是什么?我们已经把成型机交给了富新康。我们的产品线用于给手机上色。当我们把所有已经交付的手机(Aggregate)放到不同的产线(Iterator)中,它会帮我们把当前产线的颜色一一涂上,是不是很厉害!!技术不仅限于换壳。这条线还在,所以我们可以做其他事情,比如加一些挂绳。反正只要能一一过关,我就可以装东西。你觉得它好用吗?便于使用!!完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/07.iterator/source/iterator.php这个例子还是围绕我们的短信发送展开的。这次我们的业务需求是第一时间给用户发送一批通知短信,因为活动期间没有人等待。以前我们会使用多个脚本,将用户的手机号分成多个组发送。现在我们可以使用swoole直接多线程发送。要实现的效果其实就是快速??发送完几十万条短信。这个时候,我们也会做一些策略。比如数据库中有100条要发送的短信,有发送状态字段。一个线程按正常顺序发送,另一个线程按相反顺序发送。当正向和反向订单都发送到50时,实际上100条消息已经同步发送,但是可能会出现失败。这时候两个线程会继续发送那些上次没有成功的消息,这样可以最大程度的保证发送。效率和范围。消息发送迭代器类图完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/07.iterator/source/iterator-msg.phplist=$list;$this->index=0;}publicfunctionFirst(){$this->index=0;}publicfunctionNext(){$this->index++;}publicfunctionIsDone(){return$this->index>=count($this->list);}publicfunctionCurrentItem(){return$this->list[$this->index];}}//反向迭代器类MsgIteratorDesc实现MsgIterator{private$list;私人索引;publicfunction__construct($list){//反转数组$this->list=array_reverse($列表);$this->index=0;}publicfunctionFirst(){$this->index=0;}publicfunctionNext(){$this->index++;}publicfunctionIsDone(){return$this->index>=count($this->list);}publicfunctionCurrentItem(){return$this->list[$this->index];}}interfaceMessage{publicfunctionCreateIterator($list);}classMessageAscimplementsMessage{publicfunctionCreateIterator($list){returnnewMsgIteratorAsc($list);}}classMessageDescimplementsMessage{publicfunctionCreateIterator($list){returnnewMsgIteratorDesc($list);}}//待发短信号码列表$mobileList=['13111111111','13111111117','13111111113','13111111114','13111111115','13111111116','13111111117','13111'server11发送,1/8脚本]woole;$serverA=newMessageAsc();$iteratorA=$serverA->CreateIterator($mobileList);尽管(!$iteratorA->IsDone()){echo$iteratorA->CurrentItem(),PHP_EOL;$iteratorA->Next();}//B服务器脚本或者使用swoole同步发送一半反向$serverB=newMessageDesc();$iteratorB=$serverB->CreateIterator($mobileList);while(!$iteratorB->IsDone()){echo$iteratorB->CurrentItem(),PHP_EOL;$iteratorB->Next();}就是两个迭代器,一个顺序一个逆序,然后遍历数组。在示例中,我们仍然对数组进行操作。另外,我们使用两个类似于工厂方法模式的类来封装迭代器。例子很简单,但有时候这种用法也很实用。例如,某些搜索引擎排名爬虫会反复确认某些关键字的排名。这时候我们就可以验证前向和后向了。完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/06.observer/source/spl_observer.php彩蛋PHP中的Iterator接口为我们准备了一套标准的Iterator模式实现,并且(这里需要划重点),实现这个接口类就可以用foreach遍历了!文档:https://www.php.net/manual/zh/class.iterator.php源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/07.iterator/source/iterator-php.php文件中的相关接口可以查看。更重要的是,在PHP的SPL扩展中,还为我们准备了很多常用的迭代器包。要知道,如果你在面试的时候能说出其中的几个,面试官会印象深刻的!SPL迭代器:https://www.php.net/manual/zh/spl.iterators.php接下来的一点就是迭代器很好玩,和观察者一样,PHP自带的扩展库为我们准备了很多接口。平时写代码的时候是不是可以大显身手了!!别着急,我们还没有进入设计模式的世界,还有很多有趣的设计模式等着我们去学习,就像原型模式一样,这家伙在干什么?复制自己哦,克隆人大战!各媒体平台均可搜索【硬核项目经理】