精华内容
下载资源
问答
  • Facade
    2019-09-05 14:23:44
    #include <iostream>
    
    using namespace std;
    
    class SubSystem1{
    public:
        void operation(){ cout<<"SubSystem1 Operation"<<endl; }
    };
    
    class SubSystem2{
    public:
        void operation(){ cout<<"SubSystem2 Operation"<<endl; }
    };
    
    class SubSystem3{
    public:
        void operation(){ cout<<"SubSystem3 Operation"<<endl; }
    };
    
    class Facade{
    public:
        void operation()
        {
            system1.operation();
            system2.operation();
            system3.operation();
        }
    
    private:
        SubSystem1 system1;
        SubSystem2 system2;
        SubSystem3 system3;
    };
    
    int main()
    {
        cout << "Hello World!" << endl;
    
        Facade * facade = new Facade();
        facade->operation();
    
        delete  facade;
        facade = nullptr;
        return 0;
    }
    

     

    更多相关内容
  • 本文实例讲述了thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法。分享给大家供大家参考,具体如下: tp5.1中引入了容器(Container)和门面(Facade)这两个新的类 官方文档已经给出了定义: 容器...
  • import { InputFacade , facade , filter } from 'vue-input-facade' export default { components : { InputFacade } , directives : { facade } , filters : { facade : filter } , // ... rest of component
  • 本文主要给大家介绍了关于Laravel中Facade加载过程与原理的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 简介 Facades(读音:/fəˈsäd/ )为应用程序的 服务容器 中可用的类...
  • 主要介绍了Laravel框架DB facade数据库操作,结合实例形式详细分析了laravel数据库基本创建、连接、增删改查等操作技巧,需要的朋友可以参考下
  • Python笔记之facade模式

    2020-09-18 10:43:06
    主要为大家详细介绍了Python笔记之facade模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层次的接口,使得子系统更加容易使用【GOF95】 外部与子系统的通信是通过一个门面(Facade)对象进行。 二、门面模式结构图 三、门面模式中主要角色 ...
  • facade字体

    2019-10-22 19:21:11
    facade字体是一款用于线条设计方面的字体
  • 主要介绍了PHP设计模式之外观模式(Facade),结合实例形式详细分析了PHP外观模式的具体原来、用法及相关操作注意事项,需要的朋友可以参考下
  • 主要介绍了C#设计模式之Facade外观模式解决天河城购物问题,简单描述了外观模式的定义并结合具体实例分析了外观模式解决购物问题的相关步骤与操作技巧,需要的朋友可以参考下
  • Facade模式

    2019-03-22 01:37:26
    NULL 博文链接:https://gary0416.iteye.com/blog/904436
  • 主要介绍了Java设计模式之外观模式(Facade模式)介绍,外观模式(Facade)的定义:为子系统中的一组接口提供一个一致的界面,需要的朋友可以参考下
  • 主要介绍了PHP设计模式:外观模式Facade,结合实例形式详细分析了PHP外观模式Facade相关概念、功能、原理、用法与操作注意事项,需要的朋友可以参考下
  • git clone https://github.com/thealah/rest-windows-service-health-facade.git npm install 启动服务器 npm start 作为Windows服务安装 npm install node-windows node ./windows-service --install 其他Windows...
  • 语言:English 幕墙施工-斯德哥尔摩经济高效的幕墙翻新工程。 如今,您可以找到大量的外墙服务。 为了方便我们,建筑师和工程师发明了新的想法和新的设计。 在所有这些之中,选择最佳的一个并不容易。...
  • 外观模式facade

    2019-03-24 01:31:04
    NULL 博文链接:https://hnzhoujunmei.iteye.com/blog/1033285
  • Laravel开发-symfonys-facade 为Laravel框架设计的symfonys立面。
  • 提出了一种优化模式的多层架构体系,详细分析了Pet Shop的典型三层架构及使用的Factory模式、Duwamish的多层架构及使用的Facade模式,比较两者不足,综合各自优势,提出目标系统开发架构,更侧重于优化架构的设计、...
  • Command和Facade设计模式

    2019-03-19 01:30:53
    NULL 博文链接:https://smallbee.iteye.com/blog/708507
  • Swing小游戏,涉及MVC、Facade、Builder、策略、责任链等开发模式,实实在在的案例,源码和.exe全部奉上。ctrl为发射,上下左右键为方向移动。
  • 阅读建议 在阅读这篇文章之前,我...如果你使用过第三方的 composer 包,它会提醒你,把它的 ServiceProvider 和 Facade 写入到 config/app.php 文件中,如下: 当然了,注册 Facade 和 ServiceProvider 不止这么一

    阅读建议

    在阅读这篇文章之前,我希望您对 Laravel 的容器具有一定的使用和了解,如果不熟悉的话,请阅读 Laravel 容器,这方面的知识对于理解我今天要讲的东西非常有必要,再次提醒一下各位,这篇博文容量很大,仔细体会消化,希望能有所收获。

    注册 Facade

    如果你使用过第三方的 composer 包,它会提醒你,把它的 ServiceProvider 和 Facade 写入到 config/app.php 文件中,如下:

    在这里插入图片描述

    当然了,注册 Facade 和 ServiceProvider 不止这么一种方式,你感兴趣的话,可以看看官方的文档有很清楚的描述,开发第三方 Laravel 包

    这些东西都没啥可说的,如果我就说这些,也许兄弟们会说,我都知道,你还说个啥?也确实,如果就说这个,我也不好意思了,可是,后面的内容就不那么容易了。

    为了给兄弟们讲 Facade,我还是大致的给大家讲解一下 Laravel 的引导过程(只关注与 Facade 有关的部分),大家都知道 Laravel 的入口文件为 public/index.php,下面的这行代码很关键。

    在这里插入图片描述

    那么这个文件干啥了呢?现在我们只关心下面这两行:

    在这里插入图片描述

    上面创建了一个 Application 类的对象,这个类代表了我们当前的应用程序,也是整个 Laravel 最为核心的类,注意了 Application 类继承自 Container 类(这个类就是 Laravel 容器的核心),所以我们可以在 Application 类的对象上操作容器的方法,这就是为啥我在这篇博文的开头,提醒大家需要一定的容器的知识。

    在这里插入图片描述

    上面的这段代码,向容器中添加了一个单例,所以当我们创建 Illuminate\Contracts\Http\Kernel::class 对象的时候,实际上是创建的 App\Http\Kernel::class 类的对象,这一点极其重要,希望大家一定要记住,这在后面会使用到。

    回到 index.php 文件中,继续看下面这行代码:

    在这里插入图片描述

    Illuminate\Contracts\Http\Kernel::class 指向的是谁啊?不就是我们上面说的 App\Http\Kernel::class,这个文件的位置如下:

    在这里插入图片描述

    这个 Kernel 就是我们的目标了,我们打开看一下这个文件:

    在这里插入图片描述

    这个 Kernel 类继承自了 Illuminate\Foundation\Http\Kernel 类,兄弟们记住这一点,后面会使用到,下面我们回到 index.php 文件中,laravel 调用:

    在这里插入图片描述

    $kernel 的 handle 方法被调用,通过上面的分析,我们知道这个 handle 方法属于 Illuminate\Foundation\Http\Kernel 类的,对于我们分析 Facade 来说,只有一行代码是关键的,就是下面:

    在这里插入图片描述

    我们看一下这个方法 sendRequestThroughRouter,我们不必关心它的参数 $request 是啥,它对我们分析当前的目标一点儿关系都没有,这个函数中也只有一行是我们关心的,如下:

    在这里插入图片描述

    bootstrap 方法很简单,如下:

    在这里插入图片描述

    这里首先调用 bootstrappers 方法,这个方法的返回值是一个数组,它的内容如下:

    在这里插入图片描述

    上面这个我们只需要关心 RegisterFacades 类,回到 bootstrap 方法中,它调用 app->bootstrapWith 方法,这里的 app 是谁呢?他就是 Application 类的对象,这个对象在整个 Laravel 的生命周期中是唯一的,因为他是单例的,既然知道这个了,我们看 Application 对象的 bootstrapWith 方法。

    在这里插入图片描述

    还记得我们的 Application 类继承自 Container 类么?所以它可以使用 make 方法,上面说了,我们当前只关心 RegisterFacades 这个 bootstrapper,所以,我们进入到这个类的 bootstrap 方法:

    在这里插入图片描述
    在这里插入图片描述

    因为这篇博文主要给大家讲解 Facade 的整个实现的,所以我会忽略掉一些细节,关于这些细节,以后我会给大家讲解,但是在这里我会先说明他们的作用。上面这张图,我已经标注了序号,序号 1 这行代码返回了 config/app.php 文件的 aliases 字段值,我们自己的 Facade 就注册在了这个地方,在这篇博文的开头,我已经给大家说过了。序号 2 的作用是干啥呢?还记得我开始说的么?当我们开发 laravel 包的时候,可以让 laravel 自动加载我们的 ServiceProvider 和 Facade,我们所要做的就是在我们的 composer.json 中,加入下面的这段:

    在这里插入图片描述

    上面这个截图,大家应该可以看的很清楚,我就不再详述了,PackageManifest 类的作用就是负责自动加载我们在 composer.json 文件中的 ServiceProvider 和 Facade。这么说大家应该明白了吧。

    回到 RegisterFacades 类的 bootstrap 方法中,array_merge 方法合并 1 和 2 的 Facade,并把它传递给 AliasLoader 的 getInstance 静态方法。
    这个 getInstance 方法返回了一个 AliasLoader 类的对象,下面我们看它的 register 方法:

    在这里插入图片描述

    这个方法很简单,直接调用方法 prependToLoaderStack,如下:

    在这里插入图片描述

    spl_autoload_register 这个方法可能很多人不知道,因为现在都是使用成熟的框架了,简单来说,它的作用就是负责加载我们的类文件的,你有没有好奇过,php 是如何找到并加载我们的 php 类文件的,这当中的功臣就是 spl_autoload_register 了,如果你不知道它,请参考 php 的官方文档 spl_autoload_register,它的第一个参数是一个回调方法,作用就是负责加载类文件的,我们的程序中可以多次调用 spl_autoload_register 方法,也就是说可以注册多个加载函数,关于 spl_autoload_register 的介绍就这么多了,回到当前的代码中,laravel 注册的自动加载函数为 AliasLoader 对象的 load 方法,我们看哈:

    在这里插入图片描述

    这个方法我们只需要看标注出来的部分,aliases 属性存储着之前解析的所有的 Facade,部分截图如下:

    在这里插入图片描述

    之所以我会把部分标出来,是因为我后面会用到,上面的代码中使用到了 class_alias 方法,这个方法是给一个类取个别名,比如说对于 Illuminate\Support\Facades\Route::class 这个类,它的别名为 Route,为了证实这一点,我们来测试一下,在我们的路由文件中,我们经常这么做:

    在这里插入图片描述

    注意了我们并没有引入 Route 这么一个东西,但是为啥 php 没报错呢?这就是我们上面给 Illuminate\Support\Facades\Route::class 取了 Route 这个别名的原因,你可以把 class_alias 这段代码删除掉,肯定会报错的:

    在这里插入图片描述

    你再刷新一下页面,页面报错了,哈哈,就是这么刺激:

    在这里插入图片描述

    实例分析

    上面分析了 Laravel 的整个 Facade 注册的过程,是不是有点儿懵?不要慌,后面还有,任重而道远啊。

    在 Facade 注册一节中,我们标注了 Route 这个 Facade,所以这一节,就以它为例来进行讲解,Route 类如下:

    在这里插入图片描述

    所有的 Facade 都继承自 Illuminate\Support\Facades\Facade 类,并且都必须实现 getFacadeAccessor 这个方法,不然会抛出异常的,我们看 Route 的 getFacadeAccessor 方法如下,他返回字符串”router”,至于它的作用,我们后面会讲到:

    在这里插入图片描述

    为了给大家讲解后面的问题,我写了一个很简单的例子,如下:

    在这里插入图片描述

    在路由文件中,我用 Route 注册了一个路由,这里调用了 get 方法,但是我们打开 Illuminate\Support\Facades\Facade\Route 类,这个方法是不存在的,它的父类也没有,然而我们注意到了 Illuminate\Support\Facades\Facade 类实现了__callStatic 方法,如下:

    在这里插入图片描述

    callStatic 简单来说就是如果你调用某个类的静态方法,但是这个静态方法不存在的话,就会调用这个类的 callStatic 方法,如果你还是不清楚,可以网上查阅相关资料,这里不再阐述。好了,废话不多说了,我们回到 Facade 的__callStatic 方法中,这个方法首先调用 getFacadeRoot 方法,如下:

    在这里插入图片描述

    看到没,这里就是我上面说的 Facade 为啥必须实现 getFacadeAccessor 方法,在当前的实例中,它返回的是 “router“.。
    resolveFacadeInstance 方法是啥呢?很简单,但是我还是准备贴出来:

    在这里插入图片描述

    因为 Illuminate\Support\Facades\Facade 类是所有的 Facade 的父类,所以任何的 Facade 调用静态方法,都会进入到这个方法中,静态属性 $resolvedInstance 存储着当前所有被解析的 Facade 对应的实例对象,你要记住任何的 Facade 后面都有一个对象的,而且这个对象在整个 Laravel 程序的生命周期中是唯一的,只有这么一个实例,上面标注的 1 首先检查之前是否已经解析过这么一个对象,如果解析过了,直接返回就是了,这是单例的常见手法。如果之前没有解析过的话,那么代码就会走到 2 整个地方了,我们知道 $app 就是全局唯一的 Application 类对象,它继承了 Illuminate\Container\Container,而 Illuminate\Container\Container 又实现了接口 ArrayAccess,对于 ArrayAccess 接口不熟悉的同学,可以查阅相关的资料,简单来说,如果你的类实现了 ArrayAccess 接口,那么你就可以像获取数组元素一样,获取对象的内容而不会出错。

    在这里插入图片描述

    这个接口有几个方法必须实现,offsetGet 方法是其中之一,当你采用数组的写法作用在对象上时,offsetGet 会被调用,我们看 Illuminate\Container\Container 类的 offsetGet 方法,如下

    在这里插入图片描述

    在当前情况下我们获取的是 $app [‘router’],所以这里的参数 $key 就是”router”,关于容器的 make 方法,请大家参考文档,非常简单:

    在这里插入图片描述

    make 是容器暴露给我们获取容器注册内容的少有几个方法,好了,现在我们的疑问是我们什么时候注册了一个”router” 这么一个东西,大家如果使用的是 phpstorm 的话,可以这么做:

    在这里插入图片描述

    搜索内容为”router”,如下:

    在这里插入图片描述

    通过搜索我们知道,在 Illuminate\Routing\RoutingServiceProvider 这个类中,注册了 router 的单例,你可能会问,这段代码是啥时候调用的,也就是 registerRouter 方法是啥时候被调用的,当前的 RoutingServiceProvider 中的 register 方法如下:

    在这里插入图片描述

    那么 register 方法是怎么被调用的呢?不知道没关系,我细细道来,在之前的 laravel 框架引导过程中,创建 Application 类实例的时候,它的构造函数如下:

    在这里插入图片描述

    registerBaseServiceProviders 方法如下:

    在这里插入图片描述

    看见没,这个地方出现了 RoutingServiceProvider 类对象,我们再进入到 Application 类的 register 方法中,如下:

    在这里插入图片描述

    啊哈,register 方法被调用了,这个时候名为 router 的单例就被注册了,分析了这些,我们回到 RoutingServiceProvider 类的 registerRouter 方法中。

    在这里插入图片描述

    这里直接返回了 Illuminate\Routing\Router 类的实例,这个实际上就是 Laravel 全局唯一的路由器对象,路由就是靠它来实现的,分析了这些,我们再一次回到 Illuminate\Support\Facades\Facade 类的 resolveFacadeInstance 方法中。

    在这里插入图片描述

    这里把解析的实例存储到 $resolvedInstance 属性中,这样下次就不需要解析了,resolveFacadeInstance 方法调用完毕之后,返回到 Facade 的 getFacadeRoot 方法中。

    在这里插入图片描述

    上面也是直接返回刚才获取到的对象 Router 实例对象,getFacadeRoot 方法调用完毕之后,继续返回到__callStatic 方法中。

    在这里插入图片描述

    红色的代码就是翻译一下就是:

     $router->get('/',function () {
        echo "Hello World";
    })
    

    令人欣喜的是奇迹出现了,Illuminate\Routing\Router 类有如下的代码:

    在这里插入图片描述

    总结

    Laravel 的源代码错综复杂,理解起来不是那么容易,上面给大家标注出了主要的脉络,希望大家仔细体会和理解。


    更多学习内容可以访问【对标大厂】精品PHP架构师教程目录大全,只要你能看完保证薪资上升一个台阶(持续更新)

    以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的PHP技术交流群953224940

    进阶PHP月薪30k>>>架构师成长路线【视频、面试文档免费获取】

    展开全文
  • 关于facade这个词的翻译 facade这个词,原意指的是一个建筑物的表面、外观,在建筑学中被翻译为“立面”这个术语,国内对facade这个词的关注,可能更多要依赖于laravel的流行,似乎都一致把laravel里的facade翻译作...
  • Facade为AutoHotkey提供了安全可靠的界面。 自动热键问题 立面解决方案 AutoHotkey是冗长的。 通过要求程序员写更多的代码来描述相同的行为,这使得编写代码变得困难,并且通过限制程序员一次可以看到的代码数量,...
  • js_facade_gen:产生包裹

    2021-05-02 13:09:02
    执行npm install -g dart_js_facade_gen进行安装。 用法 基本的 dart_js_facade_gen <input d.ts file> Dart Interop门面文件将写入stdout。 先进的 dart_js_facade_gen --destination=<destination> --base-...
  • 古特的Laravel门面 该存储库实现了一个简单的 ,可以通过的... " description " : " A dummy project used to test the Laravel Goutte Facade. " , // ... " require " : { " php " : " ^7.2 " , " laravel/framew
  • <?... namespace Illuminate\Support\Facades;...abstract class Facade { /** * The application instance being facaded. * 被外观化的应用程序实例。 * @var \Illuminate\Contracts\Foundation.
    <?php
    
    namespace Illuminate\Support\Facades;
    
    use Mockery;
    use RuntimeException;
    use Mockery\MockInterface;
    
    abstract class Facade
    {
        /**
         * The application instance being facaded.
         * 被外观化的应用程序实例。
         * @var \Illuminate\Contracts\Foundation\Application
         */
        protected static $app;
    
        /**
         * The resolved object instances.
         * 解析的对象实例。
         * @var array
         */
        protected static $resolvedInstance;
    
        /**
         * Hotswap the underlying instance behind the facade.
         * 热交换外观背后的底层实例
         * @param  mixed  $instance
         * @return void
         */
        public static function swap($instance)
        {
            static::$resolvedInstance[static::getFacadeAccessor()] = $instance;
    
            static::$app->instance(static::getFacadeAccessor(), $instance);
        }
    
        /**
         * Initiate a mock expectation on the facade.
         * 在外观上发起模拟期望。
         * @param  mixed
         * @return \Mockery\Expectation
         */
        public static function shouldReceive()
        {
            $name = static::getFacadeAccessor();
    
            if (static::isMock()) {
                $mock = static::$resolvedInstance[$name];
            } else {
                $mock = static::createFreshMockInstance($name);
            }
    
            return call_user_func_array([$mock, 'shouldReceive'], func_get_args());
        }
    
        /**
         * Create a fresh mock instance for the given class.
         * 为给定的类创建一个新的模拟实例。
         * @param  string  $name
         * @return \Mockery\Expectation
         */
        protected static function createFreshMockInstance($name)
        {
            static::$resolvedInstance[$name] = $mock = static::createMockByName($name);
    
            $mock->shouldAllowMockingProtectedMethods();
    
            if (isset(static::$app)) {
                static::$app->instance($name, $mock);
            }
    
            return $mock;
        }
    
        /**
         * Create a fresh mock instance for the given class.
         * 为给定的类创建一个新的模拟实例。
         * @param  string  $name
         * @return \Mockery\Expectation
         */
        protected static function createMockByName($name)
        {
            $class = static::getMockableClass($name);
    
            return $class ? Mockery::mock($class) : Mockery::mock();
        }
    
        /**
         * Determines whether a mock is set as the instance of the facade.
         * 确定是否将模拟设置为外观的实例。
         * @return bool
         */
        protected static function isMock()
        {
            $name = static::getFacadeAccessor();
    
            return isset(static::$resolvedInstance[$name]) && static::$resolvedInstance[$name] instanceof MockInterface;
        }
    
        /**
         * Get the mockable class for the bound instance.
         * 获取绑定实例的可模拟类。
         * @return string|null
         */
        protected static function getMockableClass()
        {
            if ($root = static::getFacadeRoot()) {
                return get_class($root);
            }
        }
    
        /**
         * Get the root object behind the facade.
         * 获取门面后面的根对象。
         * @return mixed
         */
        public static function getFacadeRoot()
        {
            return static::resolveFacadeInstance(static::getFacadeAccessor());
        }
    
        /**
         * Get the registered name of the component.
         * 获取组件的注册名称。
         * @return string
         *
         * @throws \RuntimeException
         */
        protected static function getFacadeAccessor()
        {
            throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
        }
    
        /**
         * Resolve the facade root instance from the container.
         * 从容器解析外观根实例。
         * @param  string|object  $name
         * @return mixed
         */
        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];
        }
    
        /**
         * Clear a resolved facade instance.
         * 清除已解析的外观实例。
         * @param  string  $name
         * @return void
         */
        public static function clearResolvedInstance($name)
        {
            unset(static::$resolvedInstance[$name]);
        }
    
        /**
         * Clear all of the resolved instances.
         * 清除所有已解决的实例。
         * @return void
         */
        public static function clearResolvedInstances()
        {
            static::$resolvedInstance = [];
        }
    
        /**
         * Get the application instance behind the facade.
         * 获取外观背后的应用程序实例。
         * @return \Illuminate\Contracts\Foundation\Application
         */
        public static function getFacadeApplication()
        {
            return static::$app;
        }
    
        /**
         * Set the application instance.
         * 设置应用程序实例。
         * @param  \Illuminate\Contracts\Foundation\Application  $app
         * @return void
         */
        public static function setFacadeApplication($app)
        {
            static::$app = $app;
        }
    
        /**
         * Handle dynamic, static calls to the object.
         * 处理对对象的动态、静态调用。
         * @param  string  $method
         * @param  array   $args
         * @return mixed
         *
         * @throws \RuntimeException
         */
        public static function __callStatic($method, $args)
        {
            $instance = static::getFacadeRoot();
    
            if (! $instance) {
                throw new RuntimeException('A facade root has not been set.');
            }
    
            switch (count($args)) {
                case 0:
                    return $instance->$method();
                case 1:
                    return $instance->$method($args[0]);
                case 2:
                    return $instance->$method($args[0], $args[1]);
                case 3:
                    return $instance->$method($args[0], $args[1], $args[2]);
                case 4:
                    return $instance->$method($args[0], $args[1], $args[2], $args[3]);
                default:
                    return call_user_func_array([$instance, $method], $args);
            }
        }
    }
    

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,768
精华内容 22,707
关键字:

facade

友情链接: Stitch.rar