成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Decorator Pattern With Laravel 裝飾者模式

roundstones / 2291人閱讀

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

Decorator Pattern 裝飾者模式

綱要:

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

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

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

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

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

call_user_func() 不懂就點(diǎn)我

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 "從前有個(gè)程序員想找個(gè)女朋友.";
                    $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));
   先別著急看代碼,先讓代碼運(yùn)行下,看看結(jié)果是什么怎么樣的?然后再去分析代碼,
   效果會(huì)好一點(diǎn).ok,為了照顧新手朋友,我把執(zhí)行過程,給大家梳理一下吧.
   

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

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

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

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

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

    function()use($a,$b){    
                      #此時(shí)$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 "從前有個(gè)程序員想找個(gè)女朋友."; =>echo ""找了許久,仍未任何起色,突然有一天,碰見心儀的女神,結(jié)果,女神說:"=>"我看不上屌絲"

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

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

文件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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/30576.html

相關(guān)文章

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

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

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

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

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

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

    Luosunce 評(píng)論0 收藏0
  • 裝飾模式Decorator Pattern

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

    gityuan 評(píng)論0 收藏0
  • 設(shè)計(jì)模式裝飾模式

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

    chuyao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<