我知道laravel使用外墙。但基本上我无法绕开它为什么要使用它。让我们看一下文件外观类。为什么在已经拥有FileSystem类的情况下将File类作为门面?我们不能在代码中写这样的东西吗?
$file = new \Illuminate\FileSystem();
$path = $file->get(public_path("test.txt"));
但是laravel决定使用File Facade类,之后我可以编写如下内容:
$path = File::get(public_path("test.txt"));
美女住在哪里?如果您查看外观模式,当您可以使用两行外观进行操作时,它使您可以更轻松地进行大型工作并且不使用10行代码,但是laravel的外观使其难以理解。
难道是因为他们做了门面课,所以它像单身汉一样工作,这是它的神奇之处吗?但是,为什么单身人士会令人惊奇?
我不明白laravel立面的主意是什么。
答案 0 :(得分:2)
Laravel 具有与 Facade 设计模式相似的功能,也称为 Fades 。这个名称可能会使您感到困惑,因为Laravel中的外墙无法完全实现Facade设计模式。根据{{3}}
外观为应用程序的服务容器中可用的类提供了“静态”界面。
因此,Facade将使我们能够使用界面,而不必担心其背后的实际实现。
让我们以Laravel Cache系统为例。
当我们致电$items = Cache::get('items:popular');
在这里,我们借助Cache Facade从缓存中检索项目。
所有外观类都是从基础外观类扩展的。只有一种方法必须在每个Facade类中实现: getFacadeAccessor(),该方法返回IoC容器内的唯一服务名称。因此,它必须返回一个字符串,然后将其解析出IoC容器。
这是 Illuminate \ Support \ Facades \ Cache 门面类的源代码:
<?php
namespace Illuminate\Support\Facade;
class Cache extends Facade
{
protected static function getFacadeAccessor()
{
return 'cache';
}
}
似乎我们正在调用 Cache 类的静态方法get()
,但是正如我们所看到的,中没有这样的 static 方法缓存类。这里的方法get()
实际上存在于容器内部的服务中。所有的魔法都隐藏在基本的 Facade 类中。
在 Facade 类中,我们有__callStatic()
方法。每次调用外观上不存在的静态方法时,都会触发__callStatic()
。因此,在调用Cache::get('items:popular')
之后,我们进入了此方法,然后借助getFacadeRoot()方法在IoC容器中解析出外观背后的服务实例。该方法的代码是
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);
}
方法getFacadeRoot()
返回外观背后服务对象的实例。在这种情况下,它最终指向 CacheManager 类。在 CacheManager 类中,我们有一个getDefaultDriver()
方法,该方法将从.env
文件中获取默认的缓存配置。
public function getDefaultDriver()
{
return $this->app['config']['cache.default'];
}
获取默认缓存配置后,使用__call()
的PHP魔术方法尝试在默认缓存(redis,数据库,memcached)的 Concrete Class 上调用get()
方法等)。
因此,如果默认缓存发生更改,我们对$items = Cache::get('items:popular');
的原始调用将不会更改。大多数人将数据库用作开发的缓存,将 redis 或内存缓存用作后端。 Laravel Facades 的工作是找出要执行哪些操作才能从缓存中获取价值。例如。 redis 的get()
实现是
public function get($key)
{
$value = $this->connection()->get($this->prefix.$key);
return ! is_null($value) ? $this->unserialize($value) : null;
}
遭到巨灾的get()
实现是
public function get($key)
{
$value = $this->memcached->get($this->prefix.$key);
if ($this->memcached->getResultCode() == 0) {
return $value;
}
}
类似地,您可以另一个缓存具体类。 Laravel 将为您决定要调用的具体实现方式。