>  기사  >  백엔드 개발  >  PHP의 반복자 패턴에 대한 간략한 설명

PHP의 반복자 패턴에 대한 간략한 설명

青灯夜游
青灯夜游앞으로
2021-07-01 19:03:431430검색

이전 기사 "PHP의 관찰자 패턴 심층 분석"에서 PHP의 관찰자 패턴을 소개했습니다. 이 기사에서는 PHP의 반복자 패턴을 이해하는 데 도움이 됩니다.

PHP의 반복자 패턴에 대한 간략한 설명

이 패턴에 관해서는 루프 문을 언급해야 합니다. "Dahua 디자인 패턴"에서 저자는 이 모델의 학습 중요성이 이제 실제적인 중요성보다 크다고 말했습니다. 물론 foreach 때문이었습니다. 모든 언어에는 배열과 객체를 빠르고 쉽게 탐색할 수 있는 이와 유사한 구문이 있으므로 반복자 패턴이 23개의 주요 디자인 패턴 중 별에서 천천히 지나가는 사람이 될 수 있습니다. 특히 PHP 언어의 강점은 해시맵 구조입니다. 당연히 다양한 편리한 배열 연산 구문이 있으며 foreach는 for보다 훨씬 더 일반적으로 사용되는 구문이기도 합니다. 사용된.

Gof 클래스 다이어그램 및 설명

GoF 정의: 객체의 내부 표현을 노출하지 않고 집계 객체의 각 요소에 순차적으로 액세스하는 방법을 제공합니다.

GoF 클래스 다이어그램

PHP의 반복자 패턴에 대한 간략한 설명

코드 구현

interface Aggregate
{
    public function CreateIterator();
}

class ConcreteAggregate implements Aggregate
{
    public function CreateIterator()
    {
        $list = [
            "a",
            "b",
            "c",
            "d",
        ];
        return new ConcreteIterator($list);
    }
}

첫 번째는 반복 가능한 클래스인 집계 클래스입니다. 저는 객체 지향 디자인 패턴이기 때문에 반복자 패턴은 클래스의 내용을 반복하는 것을 목표로 합니다. 실제로 여기서는 배열을 시뮬레이션하여 반복자에게 전달했습니다.

interface MyIterator
{
    public function First();
    public function Next();
    public function IsDone();
    public function CurrentItem();
}

class ConcreteIterator implements MyIterator
{
    private $list;
    private $index;
    public function __construct($list)
    {
        $this->list = $list;
        $this->index = 0;
    }
    public function First()
    {
        $this->index = 0;
    }

    public function Next()
    {
        $this->index++;
    }

    public function IsDone()
    {
        return $this->index >= count($this->list);
    }

    public function CurrentItem()
    {
        return $this->list[$this->index];
    }
}

반복자가 처음 출시되었으며 주로 컬렉션 데이터에 대해 작동하는 네 가지 방법을 구현합니다. 데이터 구조나 데이터베이스를 배울 때 커서로 수행하는 작업과 약간 비슷합니다. First()와 Next()를 사용하여 커서를 이동하고, CurrentItem()을 사용하여 현재 커서의 데이터 내용을 가져오고, IsDone()을 사용하여 다음 데이터가 있는지 확인합니다. 따라서 이 모드를 커서 모드라고도 합니다.

$agreegate = new ConcreteAggregate();
$iterator = $agreegate->CreateIterator();

while (!$iterator->IsDone()) {
    echo $iterator->CurrentItem(), PHP_EOL;
    $iterator->Next();
}

클라이언트가 작동하는 동안 직접 사용할 수 있습니다.

  • 이터레이터 인터페이스 클래스 이름이 Iterator가 아닌 이유가 궁금하시죠? 시도해 보면 PHP가 우리를 위해 이 인터페이스를 준비했다는 것을 알게 될 것입니다. 이를 구현한 후 foreach를 사용하여 Iterator 인터페이스를 구현하는 이 클래스를 사용할 수 있습니다. 마지막으로 이 클래스의 사용법을 살펴보겠습니다.
  • 수업 순회에 동의하지 않으셨나요? 배열을 앞뒤로 전달하는 이유는 무엇입니까? Java를 개발한 학생들은 Object 클래스라는 JavaBean에서 List myList와 같은 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条了,不过也有可能会有失败的情况出现,这时,两个线程还会继续去发送那些上次发送不成功的信息,这样能够最大程度的确保发送的效率和到达率。

消息发送迭代器类图

PHP의 반복자 패턴에 대한 간략한 설명

完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/07.iterator/source/iterator-msg.php

<?php

interface MsgIterator
{
    public function First();
    public function Next();
    public function IsDone();
    public function CurrentItem();
}

// 正向迭代器
class MsgIteratorAsc implements MsgIterator
{
    private $list;
    private $index;
    public function __construct($list)
    {
        $this->list = $list;
        $this->index = 0;
    }
    public function First()
    {
        $this->index = 0;
    }

    public function Next()
    {
        $this->index++;
    }

    public function IsDone()
    {
        return $this->index >= count($this->list);
    }

    public function CurrentItem()
    {
        return $this->list[$this->index];
    }
}

// 反向迭代器
class MsgIteratorDesc implements MsgIterator
{
    private $list;
    private $index;
    public function __construct($list)
    {
        // 反转数组
        $this->list = array_reverse($list);
        $this->index = 0;
    }
    public function First()
    {
        $this->index = 0;
    }

    public function Next()
    {
        $this->index++;
    }

    public function IsDone()
    {
        return $this->index >= count($this->list);
    }

    public function CurrentItem()
    {
        return $this->list[$this->index];
    }
}

interface Message
{
    public function CreateIterator($list);
}

class MessageAsc implements Message
{
    public function CreateIterator($list)
    {
        return new MsgIteratorAsc($list);
    }
}
class MessageDesc implements Message
{
    public function CreateIterator($list)
    {
        return new MsgIteratorDesc($list);
    }
}

// 要发的短信号码列表
$mobileList = [
    &#39;13111111111&#39;,
    &#39;13111111112&#39;,
    &#39;13111111113&#39;,
    &#39;13111111114&#39;,
    &#39;13111111115&#39;,
    &#39;13111111116&#39;,
    &#39;13111111117&#39;,
    &#39;13111111118&#39;,
];

// A服务器脚本或使用swoole发送正向的一半
$serverA = new MessageAsc();
$iteratorA = $serverA->CreateIterator($mobileList);

while (!$iteratorA->IsDone()) {
    echo $iteratorA->CurrentItem(), PHP_EOL;
    $iteratorA->Next();
}

// B服务器脚本或使用swoole同步发送反向的一半
$serverB = new MessageDesc();
$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

本文转载自:https://juejin.cn/post/6844903937921777671

作者:硬核项目经理

推荐学习:《PHP视频教程

위 내용은 PHP의 반복자 패턴에 대한 간략한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제