结合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中$method(...$args)的意义

laravel中$method(...$args)的意义最近在学习laravel,在查看门面源码的时候在Illuminate\Support\Facades\Facade中发现了这样一句:return...
  • zjiang1994
  • zjiang1994
  • 2017年08月22日 19:07
  • 389

Laravel Facade 实现原理揭秘

在使用Laravel 框架的时候会看到很多 Cache::get() 这样的用法,称之为 Facade,门面。 但是代码中即没有看到使用 Cache 相关的命名空间,且在 Composer 自动加载中...
  • hizzana
  • hizzana
  • 2016年11月18日 09:01
  • 2680

php当中的观察者模式,在laravel框架中有用到

  • baixiaoshi
  • baixiaoshi
  • 2015年01月21日 23:32
  • 1242

对laravel5概念的理解 -- 观察者模式(Event)

官方给的tutorial完全把我搞混了,command bus queue的例子中使用了event事件,而event事件中又有事件队列。然后小白搞不懂两者区别了,最后结论么,两者根本没关系。 even...
  • cuishuli
  • cuishuli
  • 2016年07月07日 18:52
  • 2164

Ajax中使用Facade外观模式的Eclipse版本的Demo

  • 2008年06月03日 18:43
  • 502KB
  • 下载

设计模式之外观模式 facade

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

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

  • 2011年11月02日 19:54
  • 8.03MB
  • 下载

设计模式之外观模式(Facade Pattern)

  • 2012年03月06日 17:53
  • 68KB
  • 下载

C#面向对象设计模式纵横谈\11 结构型模式Facade外观模式.zip

  • 2009年12月20日 12:56
  • 7.52MB
  • 下载

C#面向对象设计模式纵横谈(11):Facade 外观模式(结构型模式) (Level 300)

  • 2008年09月13日 15:59
  • 6.06MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:结合laravel Facade看外观模式怎么用?
举报原因:
原因补充:

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