成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Decorator Pattern With Laravel 裝飾者模式

roundstones / 2229人閱讀

摘要:裝飾對象包含一個真實對象的引用裝飾對象接受所有來自客戶端的請求。裝飾對象可以在轉(zhuǎn)發(fā)這些請求以前或以后增加一些附加功能。在面向?qū)ο蟮脑O(shè)計中,通常是通過繼承來實現(xiàn)對給定類的功能擴(kuò)展。

Decorator Pattern 裝飾者模式

綱要:

 1. 一個初學(xué)者的疑惑
 
 2. 裝飾者模式的特點
 
 3. 簡單case掌握裝飾者模式
 
 4. laravel中裝飾者模式的應(yīng)用

Confusing:
剛開始研究laravel源碼之前,對于"裝飾者模式"我也是知之甚少,而對于“裝飾者模式”的學(xué)習(xí)起因于創(chuàng)建一個中間件的時候,我始終都不太明白,中間件中的$next閉包是怎么傳進(jìn)來,因此好奇心強的我google了大量的前輩的博客和文章,學(xué)到了很多以前不知道的知識點,才明白中間件加載的原理,使我受益匪淺,在此非常感謝這些前輩的無私奉獻(xiàn).ok,回到正題.

裝飾者模式的特點
詳細(xì)介紹點我

“(1) 裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。
(2) 裝飾對象包含一個真實對象的引用(reference)
(3) 裝飾對象接受所有來自客戶端的請求。它把這些請求轉(zhuǎn)發(fā)給真實的對象。
(4) 裝飾對象可以在轉(zhuǎn)發(fā)這些請求以前或以后增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結(jié)構(gòu)就可以在外部增加附加的功能。在面向?qū)ο蟮脑O(shè)計中,通常是通過繼承來實現(xiàn)對給定類的功能擴(kuò)展?!? --------------引自<百度百科>

簡單case掌握裝飾者模式
注意:若是以前沒接觸過該模式,建議先看下這篇文章《laravel 框架關(guān)鍵技術(shù)解析》學(xué)習(xí)筆記之裝飾者模式,再回頭看本文效果更佳.
好吧,如果是第一次看裝飾者模式,看上面特性"官方闡述",確實有點不知所云,ok,為方便大家能快速理解該模式,我寫了一個"laravel源碼簡化版"的case,放代碼之前給大家說下實現(xiàn)該模式最核心的東西,就靠兩個方法,如下:

call_user_func() 不懂就點我

array_reduce() 你應(yīng)該看看我

代碼:

    interface func{
        public static function handle($next);
    } 
    class beauty implements func{
        
        public static  function say($next){
            $next();
            echo "我看不上屌絲";
        }
    }

    class guy implements func{
        
            public static function say($next){
                    echo "從前有個程序員想找個女朋友.";
                    $next();
                    
            }
    }

    $e=[guy::class,beauty::class];

    function getClosure(){
        
        return function ($a,$b){
            return function()use($a,$b){
                    $b::say($a);
            };
        };
    }

    $d = function(){ echo "找了許久,仍未任何起色,突然有一天,碰見心儀的女神,結(jié)果,女神說:"."
";};

    call_user_func(array_reduce($e,getClosure(),$d));
   先別著急看代碼,先讓代碼運行下,看看結(jié)果是什么怎么樣的?然后再去分析代碼,
   效果會好一點.ok,為了照顧新手朋友,我把執(zhí)行過程,給大家梳理一下吧.
   

執(zhí)行流程:
第一步.
首先getClosure()函數(shù)調(diào)用返回的是一個閉包:

function($a,$b){
 return function()use($a,$b){
     return $b::say($a);
 }
}

第二步.
將$d和$e[0]作為第一步返回結(jié)果的參數(shù)并且執(zhí)行,返回結(jié)果:

function()use($a,$b){     
                     #此時$b="guy" 
                     #$a = $d=function(){echo "找了許久,仍未任何起色,突然有一天,碰見心儀的女神,結(jié)果,女神說:"."
";}
    return $b::say($a);
    }

第三步.
將第二部的結(jié)果和$e[1]作為第一步返回結(jié)果的參數(shù)并且執(zhí)行,返回結(jié)果:

    function()use($a,$b){    
                      #此時$b="beauty"  $a="第二步驟返回結(jié)果" 
                      #      $a = function()use($,"beacuty"){
                      #        beauty::say(function()use("guy",$d){
                      #          return guy::say($d);
                      #       })
                      #     }
    return $b::say($a);
    }
   

第四步.執(zhí)行call_user_func()調(diào)用array_reduce()返回的閉包即第三步的結(jié)果.
beauty::say($d) ==>$d()=>echo "從前有個程序員想找個女朋友."; =>echo ""找了許久,仍未任何起色,突然有一天,碰見心儀的女神,結(jié)果,女神說:"=>"我看不上屌絲"

執(zhí)行過程類似如圖(仔細(xì)體會,好似洋蔥一樣,從最外層滲透進(jìn)去到最內(nèi)層,再從最內(nèi)層到最外層):

laravel中裝飾者模式的應(yīng)用
這里給出laravel框架的源碼進(jìn)行對比分析.

文件index.php  line 50

    $kernel = $app->make(IlluminateContractsHttpKernel::class);
    
    $response = $kernel->handle(
        $request = IlluminateHttpRequest::capture()
);

文件IlluminateFoundationHttpKernel.php
  

     public function handle($request)
        {
            try {
                $request->enableHttpMethodParameterOverride();
    
                $response = $this->sendRequestThroughRouter($request);
            } catch (Exception $e) {
             ....省略異常處理
            }
    
            $this->app["events"]->fire("kernel.handled", [$request, $response]);
    
            return $response;
        }
    
    
       protected function sendRequestThroughRouter($request)
       {
        $this->app->instance("request", $request);
    
        Facade::clearResolvedInstance("request");
    
        $this->bootstrap();
    
        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
     }
    
    protected function dispatchToRouter()
    {
        return function ($request) {
            $this->app->instance("request", $request);
    
            return $this->router->dispatch($request);
        };
    }

文件IlluminatePipeLinePipeLine.php

       public function send($passable)
        {
            $this->passable = $passable;
    
            return $this;
        }
          public function through($pipes)
        {
            $this->pipes = is_array($pipes) ? $pipes : func_get_args();
    
            return $this;
        }
         public function then(Closure $destination)
    {
        $firstSlice = $this->getInitialSlice($destination);

        $pipes = array_reverse($this->pipes);

        return call_user_func(
            array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable
        );
    }
        protected function getInitialSlice(Closure $destination)
    {
        return function ($passable) use ($destination) {
            return call_user_func($destination, $passable);
        };
    }

    protected function getSlice()
    {
        return function ($stack, $pipe) {
            return function ($passable) use ($stack, $pipe) {
                // If the pipe is an instance of a Closure, we will just call it directly but
                // otherwise we"ll resolve the pipes out of the container and call it with
                // the appropriate method and arguments, returning the results back out.
                if ($pipe instanceof Closure) {
                    return call_user_func($pipe, $passable, $stack);
                } else {
                    list($name, $parameters) = $this->parsePipeString($pipe);
    
                    return call_user_func_array([$this->container->make($name), $this->method],
                            array_merge([$passable, $stack], $parameters));
                }
            };
        };
    }

文件IlluminateFoundationApplication.php 

       public function shouldSkipMiddleware()
        {
            return $this->bound("middleware.disable") &&
                   $this->make("middleware.disable") === true;
        }

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/30576.html

相關(guān)文章

  • laravel 框架關(guān)鍵技術(shù)解析》學(xué)習(xí)筆記之裝飾模式

    摘要:裝飾者模式是在開放關(guān)閉原則下實現(xiàn)動態(tài)添加或減少功能提高程序的擴(kuò)展性詳細(xì)介紹注本文可以作為學(xué)習(xí)裝飾者模式的基礎(chǔ)篇但是我個人更建議配套裝飾者模式來學(xué)習(xí)效果更佳本文中的例子是由框架關(guān)鍵技術(shù)解析中摘抄的。 裝飾者模式:是在開放-關(guān)閉原則下實現(xiàn)動態(tài)添加或減少功能,提高程序的擴(kuò)展性.詳細(xì)介紹注: 本文可以作為學(xué)習(xí)裝飾者模式的基礎(chǔ)篇,但是我個人更建議配套Decorator Pattern With...

    fuyi501 評論0 收藏0
  • Laravel學(xué)習(xí)筆記之Decorator Pattern

    摘要:把和拼接在一起的場所是,所以需要造一個類,在其內(nèi)部實現(xiàn)對的操作中實現(xiàn)了把原有的進(jìn)過個的裝飾后得到的新的,新的還是的實現(xiàn),還是原來的物種。 說明:Laravel中Middleware的實現(xiàn)主要利用了Decorator Pattern的設(shè)計,本文主要先學(xué)習(xí)下Decorator Pattern如何實現(xiàn),為后面學(xué)習(xí)Middleware的設(shè)計做個鋪墊。Decorator Pattern和Adap...

    dendoink 評論0 收藏0
  • Laravel學(xué)習(xí)筆記之Filesystem源碼解析(下)

    摘要:源碼解析這個類的源碼主要就是文件的操作和文件屬性的操作,而具體的操作是通過每一個實現(xiàn)的,看其構(gòu)造函數(shù)看以上代碼知道對于操作,實際上是通過的實例來實現(xiàn)的??梢钥聪碌氖褂蒙衔囊呀?jīng)說了,使得對各種的操作變得更方便了,不管是還是得。 說明:本文主要學(xué)習(xí)下LeagueFlysystem這個Filesystem Abstract Layer,學(xué)習(xí)下這個package的設(shè)計思想和編碼技巧,把自己的一...

    Luosunce 評論0 收藏0
  • 裝飾模式Decorator Pattern

    摘要:通常有兩種方式可以實現(xiàn)給一個類或?qū)ο笤黾有袨槔^承機制,使用繼承機制是給現(xiàn)有類添加功能的一種有效途徑,通過繼承一個現(xiàn)有類可以使得子類在擁有自身方法的同時還擁有父類的方法。 裝飾模式 (Decorator Pattern) 裝飾模式能夠?qū)崿F(xiàn)動態(tài)的為對象添加功能,是從一個對象外部來給對象添加功能。通常有兩種方式可以實現(xiàn)給一個類或?qū)ο笤黾有袨椋? 繼承機制,使用繼承機制是給現(xiàn)有類添加功能的一種...

    gityuan 評論0 收藏0
  • 設(shè)計模式裝飾模式

    摘要:相關(guān)設(shè)計模式裝飾者模式和代理模式裝飾者模式關(guān)注再一個對象上動態(tài)添加方法代理模式關(guān)注再對代理對象的控制訪問,可以對客戶隱藏被代理類的信息裝飾著模式和適配器模式都叫包裝模式關(guān)于新職責(zé)適配器也可以在轉(zhuǎn)換時增加新的職責(zé),但主要目的不在此。 0x01.定義與類型 定義:裝飾模式指的是在不必改變原類文件和使用繼承的情況下,動態(tài)地擴(kuò)展一個對象的功能。它是通過創(chuàng)建一個包裝對象,也就是裝飾來包裹真實的...

    chuyao 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<