php 管道/流水线/Pipeline模式指的是什么?

2022-09-11 17:19:08 浏览数 (1)

PHP 管道/流水线/Pipeline模式

  • 作用
代码语言:txt复制
- 其实Pipeline模式和装饰者模式类似
- 管道就是把一系列串联执行的程序按顺序分工处理举例
代码语言:txt复制
- 顾客在商城提交商品创建订单、支付很简单常见;
- 现在商城新加了一个会员卡,一级会员打 9.5 折,二级会员 9 折,三级会员 8.5 折;
- 随后需求又要加入优惠券系统,部分商品需要打折;
- 如果把这些串联执行的程序放在一起处理,代码程序看起来会越来越臃肿不堪,难以维护;
- 老员工离职,新员工入职接手这样的代码可能直接会疯掉;解决
代码语言:txt复制
- 如果把一系列串联执行的程序按顺序分工处理,按串联顺序把一系列的创建订单、会员卡打折、优惠券等等功能分别处理,这样就会很nice。
- 简单来说就是 将「输入」引入管道,根据每个小任务对输入进行操作 (加工、过滤),最后输出满足需要的结果。有对装饰者模式感兴趣的同学可以看这篇文章

装饰器模式

本次代码符合PHP规范PRS_0根目录下新建一个Frame的目录(核心目录),建立APP目录(项目目录)统一访问入...

  • 有对设计模式感兴趣的可以看这篇文章

PHP 常用的设计模式汇总

php常用的设计模式汇总自我认为,不善用设计模式的编程没有灵魂,所以大家可以学学,适当的在编码中尝试巧用一下设计模...

代码演示1

代码语言:javascript复制
<?php

interface PipelineInterface
{
    public function __construct($payLoad);

    public function pipe(StageInterface $stage);

    public function process();
}

interface StageInterface
{
    public function handle($payLoad);
}

class StageAddHundred implements StageInterface
{
    public function handle($payLoad)
    {
        return $payLoad   100;
    }
}

class StageMultiHundred implements StageInterface
{
    public function handle($payLoad)
    {
        return $payLoad * 100;
    }
}

class Pipeline implements PipelineInterface
{
    private $pipes;

    private $payLoad;

    public function __construct($payLoad)
    {
        $this->payLoad = $payLoad;
    }

    public function pipe(StageInterface $stage)
    {
        $this->pipes[] = $stage;
        return $this;
    }

    public function process()
    {
        foreach ($this->pipes as $eachPipe) {
            $this->payLoad = call_user_func([$eachPipe, 'handle'], $this->payLoad);
        }

        return $this->payLoad;
    }
}

//int(11000)
$pipe = (new Pipeline(10))
    ->pipe(new StageAddHundred())
    ->pipe(new StageMultiHundred())
    ->process();

代码演示2

  • 推荐一个 PHP 插件:league/pipeline
代码语言:javascript复制
<?php
   
   include 'vendor/autoload.php';
   
   use LeaguePipelinePipeline;
   use LeaguePipelineStageInterface;
   
   class OrderStage implements StageInterface
   {
       public function __invoke($payload)
       {
           $payload['order'] = ['info' => '我是订单详情'];
           return   $payload;
       }
   }
   
   class Stage implements StageInterface
   {
       public function __invoke($payload)
       {
          $payload['coupon'] = ['info'=>'我是优惠信息'];
           return $payload;
       }
   }
   

    $pipeline = (new Pipeline)
    ->pipe(new OrderStage)
    ->pipe(new CouponStage);
   
   $pipeline->process(array());

   /*Array
   (
       [order] => Array
       (
           [info] => 我是订单详情
       )
   
       [coupon] => Array
   (
       [info] => 我是优惠信息
   )
        
        )*/

拓展 redis中的pipeline

  • 众所周知,redis是单线程的,循环执行n个命令和打包执行n个命令对比如下

命令

时间

数据量

N个命令操作

n次网络 n命令次

n次网络 n命令次

1次pipeline(n个命令)

1条命令

1次网络 n命令次

代码直观对比

  • php操作redis(pipeline)代码
代码语言:javascript复制
<?php


$stime = microtime(true); //获取程序开始执行的时间
echo '开始内存:'.$sm = memory_get_usage(), '<hr>';
echo PHP_EOL;
$redis = new Redis();

$redis->connect('127.0.0.1', 6379);


$pipe = $redis->multi($redis::PIPELINE);

for ($i = 0; $i < 10000; $i  ) {

    $pipe->set("key::$i", str_pad($i, 4, '0', 0));

    $pipe->get("key::$i");

}

$replies = $pipe->exec();

$etime = microtime(true);//获取程序执行结束的时间

$total = ($etime - $stime);   //计算差值


echo "[页面执行时间:{$total}s<hr>";
echo '运行后内存:'.$em = memory_get_usage(), '<hr>';
//开始内存:393576
//[页面执行时间:0.070788860321045s
//运行后内存:1775136
  • php操作redis代码
代码语言:javascript复制
<?php
  $stime=microtime(true); //获取程序开始执行的时间
  echo '开始内存:'.$sm = memory_get_usage(), '<hr>';
  $redis = new Redis();
  
  $redis->connect('127.0.0.1',6379);
  
  
  
  $t1 = time();
  for($i= 0; $i<10000 ; $i  ) {
  
      $redis->set("key::$i",str_pad($i,4,'0',0));
  
      $redis->get("key::$i");
  
  }
  
  
  $etime=microtime(true);//获取程序执行结束的时间
  
  $total=($etime-$stime);   //计算差值
  
  
  echo "[页面执行时间:{$total}s<hr>";
  echo '运行后内存:'.$em = memory_get_usage(), '<hr>';

//开始内存:392968
//[页面执行时间:2.7398328781128s
//运行后内存:401800

0 人点赞