分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

php模式之装饰者模式学习

发布时间:2023-09-06 01:14责任编辑:傅花花关键词:暂无标签
<?php//装饰器模式主要是两类对象--被装饰者和装饰器对象//装饰器和被装饰者拥有一样的超类(接口)//外层装饰对象重写公共方法,并委托调用内层方法。interface Decorate {   # code...   public function display(); }   class Person implements Decorate {     public $name;     public function __construct($name)   {     $this->name = $name;     echo ‘我叫‘.$name.‘我准备出门了<br>‘;   }     public function display()   {       echo ‘我出门了<br>‘;   } } /** *装饰器1,和被装饰者一样都是属于Decorate接口的实现 **/   class Wash implements Decorate {     private $compact;        public function __construct(Decorate $compact)   {     $this->compact = $compact;          }     public function display()   {     echo ‘我是一个装饰器1,出门之前先换件衣服<br>‘;     $this->compact->display();   }   }/***装饰器2**/ class Dress implements Decorate {     private $compact;        public function __construct(Decorate $compact)   {     $this->compact = $compact;          }     public function display()   {        echo ‘我是一个装饰器2,换衣服之前,先洗把脸<br>‘;     $this->compact->display();               }   }     /** *装饰器3 **/   class Close implements Decorate {     private $compact;        public function __construct(Decorate $compact)   {     $this->compact = $compact;          }     public function display()   {            $this->compact->display();     echo ‘我是装饰器3,把门锁了<br>‘;   } }     $person = new Person(‘韩梅梅‘); //开始装饰  $dress = new Dress($person);    $wash = new Wash($dress);    $close = new Close($wash);    $close->display();


laravel中装饰器模式实现----中间件(middleware)


laravel中的实现方式可能与上面讲的不一样,但是其软件设计模式是相通的,通过对请求不断的装饰,

只是它装饰采用的是闭包传入的方式。


核心源码解析

/** * Send the given request through the middleware / router. * * @param  \Illuminate\Http\Request  $request * @return \Illuminate\Http\Response */protected function sendRequestThroughRouter($request){    $this->app->instance(‘request‘, $request);    Facade::clearResolvedInstance(‘request‘);    $this->bootstrap();    return (new Pipeline($this->app))              //发送请求到管道中                ->send($request)                //thtough()方法可以理解成在收集该请求过程中                //的中间键数组包括基础服务的和用户自定义的                ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)                ->then($this->dispatchToRouter());}

 核心方法是在then() 我们接着来看then()里面的实现

/** * Run the pipeline with a final destination callback. * * @param  \Closure  $destination * @return mixed */public function then(Closure $destination){    $pipeline = array_reduce(        array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)    //这里$this->pipes即为要通过的中间件数组,$this->carray()是一个闭包处理函数。它会   //执行当前上一次传入的闭包,同时可以决定在执行前或执行后,插入逻辑(即中间件)。   //$this->prepareDestination($destination)也是一个闭包,可以理解成没用中间件的情况    //请求过程中会执行的    );    return $pipeline($this->passable);}

这里的难点和巧妙在于mixed array_reduce( array $array, callable $callback   [, mixed $initial = NULL  ] );

官方的说法是--array_reduce — 用回调函数迭代地将数组简化为单一的值。通俗一点讲就是以$callback遍历处理$array,每次传入的是上一次回调处理的函数和当前数组元素(是不是有点像装饰者,一层一层装饰);由于篇幅有限,具体使用和理解请参考手册。

这里比较难理解的是在传入参数上,laravel框架中传入的第一个参数---中间件对象数组 。它会使用上一次处理的结果(闭包对象$next),在根据自己的handle方法,该方法接受一个参数--$next,这样就可以在$next()方法之前,或之后添加逻辑了。


指的一提的是,最后返回的还是一个闭包对象,所以在最后执行了一次,相当于启动,内部就会依次联动。



单是文字确实难以理解,后续有时间会把代码补上。


由于作者水平有限,如有错误还望海涵。





本文出自 “罗马不是一天建成的” 博客,转载请与作者联系!

php模式之装饰者模式学习

原文地址:http://wwpstl.blog.51cto.com/11150755/1969383

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved