• laravel 门面模式


    最近在学习laravel框架的各种设计原理,今天看到门面模式这了,做下笔记:

    Facade 工作原理

    在 Laravel 应用中,门面就是一个为容器中对象提供访问方式的类。该机制原理由 Facade 类实现。Laravel 自带的门面,以及我们创建的自定义门面,都会继承自 IlluminateSupportFacadesFacade 基类。

    门面类只需要实现一个方法:getFacadeAccessor。正是 getFacadeAccessor 方法定义了从容器中解析什么。然后 Facade 基类使用魔术方法 __callStatic() 代理门面上静态方法的调用,并将其交给通过 getFacadeAccessor 方法定义的从容器中解析出来的服务类来执行。

    在config/app.php文件下有这样的配置:

    'aliases' => [
    
            'App' => IlluminateSupportFacadesApp::class,
            'Artisan' => IlluminateSupportFacadesArtisan::class,
            'Auth' => IlluminateSupportFacadesAuth::class,
            'Blade' => IlluminateSupportFacadesBlade::class,
            'Broadcast' => IlluminateSupportFacadesBroadcast::class,
            'Bus' => IlluminateSupportFacadesBus::class,
            'Cache' => IlluminateSupportFacadesCache::class,
            'Config' => IlluminateSupportFacadesConfig::class,
            'Cookie' => IlluminateSupportFacadesCookie::class,
            'Crypt' => IlluminateSupportFacadesCrypt::class,
            'DB' => IlluminateSupportFacadesDB::class,
            'Eloquent' => IlluminateDatabaseEloquentModel::class,
            'Event' => IlluminateSupportFacadesEvent::class,
            'File' => IlluminateSupportFacadesFile::class,
            'Gate' => IlluminateSupportFacadesGate::class,
            'Hash' => IlluminateSupportFacadesHash::class,
            'Lang' => IlluminateSupportFacadesLang::class,
            'Log' => IlluminateSupportFacadesLog::class,
            'Mail' => IlluminateSupportFacadesMail::class,
            'Notification' => IlluminateSupportFacadesNotification::class,
            'Password' => IlluminateSupportFacadesPassword::class,
            'Queue' => IlluminateSupportFacadesQueue::class,
            'Redirect' => IlluminateSupportFacadesRedirect::class,
            'Redis' => IlluminateSupportFacadesRedis::class,
            'Request' => IlluminateSupportFacadesRequest::class,
            'Response' => IlluminateSupportFacadesResponse::class,
            'Route' => IlluminateSupportFacadesRoute::class,
            'Schema' => IlluminateSupportFacadesSchema::class,
            'Session' => IlluminateSupportFacadesSession::class,
            'Storage' => IlluminateSupportFacadesStorage::class,
            'URL' => IlluminateSupportFacadesURL::class,
            'Validator' => IlluminateSupportFacadesValidator::class,
            'View' => IlluminateSupportFacadesView::class,
    
        ],

    举个栗子,lar的缓存调用是Cache::get()这样使用的,那么Cache显然是这里做了映射,那么对应的 IlluminateSupportFacadesCache 这个又是什么,追踪到这个类看看.

    class Cache extends Facade
    {
        /**
         * Get the registered name of the component.
         *
         * @return string
         */
        protected static function getFacadeAccessor()
        {
            return 'cache';
        }
    }

    这个类只是继承了门面的基类  并定义了一个方法 返回一个cache名称,这里的cache其实是在app容器里能解析缓存类的对应名称.

    那么Cache::get是一个怎么样的过程呢,其实在Facade类里是写了静态方法重载的,源码如下

     public static function __callStatic($method, $args)
        {
            $instance = static::getFacadeRoot();
    
            if (! $instance) {
                throw new RuntimeException('A facade root has not been set.');
            }
    
            return $instance->$method(...$args);
        }
    
    public static function getFacadeRoot()
    {
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }
    
    protected static function resolveFacadeInstance($name)
    {
        if (is_object($name)) {
            return $name;
        }
    
        if (isset(static::$resolvedInstance[$name])) {
            return static::$resolvedInstance[$name];
        }
    
        return static::$resolvedInstance[$name] = static::$app[$name];
    }

    这里重载会去按cache的名称去容器里获取对象  最终还是去app容器里解析,然后获取对象后再调用get方法传入参数。

    至于怎么把Cache对应到cache的门面上 就是用到了class_alias这个方法。

    注:别名只是关联到门面类上  真正起作用的还是门面基类的重载。

  • 相关阅读:
    文件查找和压缩
    shell脚本编程基础
    [模板]数据生成与对拍
    Codeforces Round #746 (Div. 2)
    Codeforces Round #712 (Div. 2)
    Codeforces Round #715 (Div. 2)
    Codeforces Round #752 (Div. 2)
    提高模拟赛Day8T3树上跑步
    提高模拟赛Day8T2最大匹配
    提高模拟赛Day8T1求中位数
  • 原文地址:https://www.cnblogs.com/tudou1223/p/9361505.html
Copyright © 2020-2023  润新知