结合laravel Facade看外观模式怎么用?

原创 2016年10月02日 21:00:30

  当独立子系统的开发完成后,如果两个系统是客户-供应商关系,也就是说其中一个子系统(客户)需要使用另一个子系统(供应商)提供的服务时,我们可以通过外观模式来对客户子系统隐藏调用供应商系统的复杂性,客户端只需通过facade调用相应的服务而无需涉及供应商具体的服务调用方法。下面通过laravel中的facade来说明:
  
在laravel中,我们经常通过facade来实现全局调用某个方法而不需要实例化一个对象。通过查看源码可以知道,所有的Facade都是继承自同一个抽象父类Illuminate\Support\Facades\Facade

当我们调用Auth::guard(‘customer’)来返回一个guard实例的时候,只需要在调用这个方法的所在脚本写上use Illuminate\Support\Facades\Auth;就可以了,而当我们去查看Illuminate\Support\Facades\Auth的具体定义的时候,我们就会发现,这种调用都是基于php的魔术方法——__callstatic()

所有Facade中都包含了这个继承自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);
    }
}

从代码中可以看出,最关键的一句就是`$instance = static::getFacadeRoot();,因为调用的方法和参数我们都能通过callstatic获取,关键是我们如何获取到一个能执行这个方法的正确的对象,让我们继续往下扒。

  public static function getFacadeRoot()
{
  return static::resolveFacadeInstance(static::getFacadeAccessor());
}

原来底层是你,resolveFacadeInstance(static::getFacadeAccessor())不管,继续扒。

protected static function getFacadeAccessor()
    {
      throw new RuntimeException('Facade does not implement getFacadeAccessor method.');
    }

static::getFacadeAccessor()为什么直接抛出错误,搞错了?不对,刚才好像在哪见过??没错,每个Facade都会对这个方法进行重写,如果没有重写就会抛出错误,例如在 Illuminate\Support\Facades\Auth中的实现是:

    protected static function getFacadeAccessor()
    {
       return 'auth';
    }

好了,看来接下来这个才是最核心的resolveFacadeInstance($name),

 protected static function resolveFacadeInstance($name)
    {
    //判断传入参数是否是对象,是则直接返回,我意淫laravel框架告诉我们在定义自己的facade的时候可以直接在getFacadeAccessor返回一个对象
        if (is_object($name)) {
            return $name;
        }
   //不是对象的话,判断是否已经实例化过这个对象,是的话就把之前实例化后保存的对象拿去使
        if (isset(static::$resolvedInstance[$name])) {
            return static::$resolvedInstance[$name];
        }
//没有?!那只能返回新的对象并保存到$resolvedInstance中方便下次用了
        return static::$resolvedInstance[$name] = static::$app[$name];
    }

ps :这里是$app是laravel的ioc容器

通过上面的例子可以看出,laravel通过外观模式对外提供auth服务,向客户端隐藏了具体的操作,实际底层是调用了某个具体的执行者来提供该项服务,这样客户端就无需知道相关细节,就可以使用开箱即用的服务。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Laravel 中的Facades的研究

每一个facade 对应一个服务提供者类。如何从facade 解析出该类呢? 以 Illuminate\Support\Facades\Route 为例。该类内容如下,只有一个方法 ...

Laravel 门面类:Facade简记

简单剖析了Laravel的门面:Facades类的源码,解析了外部能像调用静态方法一样自由调用各个类下的非静态方法。...
  • YQXLLWY
  • YQXLLWY
  • 2017年07月06日 14:43
  • 506

Laravel 基础 - 门面

门面为应用的服务容器中的绑定类提供了一个"静态"接口。Laravel 内置了很多门面,你可能在不知道的情况下正在使用它们。Laravel 的门面作为服务容器中的底层类的"静态代理",相比于传统静态方法...

facade的调用原理和过程

1.一个类 如  ....CacheManager.php 2.一个provider ... CacheServiceProvider 3. class CacheServiceProvider ex...

RabbitMQ学习之主题topic(java)

参考:http://blog.csdn.net/lmj623565791/article/details/37706355 direct类型的消息通过绑定键转发到队列,但是存在一些局限性:它不能够基...

RabbitMQ的安装,配置,监控

上一篇提到了用MongoDB的郁闷,这一篇博客则是尝试了另外一个新东西 - RabbitMQ 的结果。所不同的是,RabbitMQ给我的感觉很棒。强力推荐! 安装 RabbitMQ是基于E...

设计模式之外观模式 facade

  • 2012年06月13日 17:41
  • 10KB
  • 下载

外观模式(facade)c++版本

大话设计模式中的外观模式c++版本/* * facade.cpp * * Created on: Jul 25, 2017 * Author: clh01s@163.com * ...
  • clh01s
  • clh01s
  • 2017年07月25日 14:32
  • 66

Facade 外观模式(结构型模式)

  • 2011年11月02日 19:54
  • 8.03MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:结合laravel Facade看外观模式怎么用?
举报原因:
原因补充:

(最多只允许输入30个字)