为什么 Laravel 主要使用 Facades 而不是单例?

Tos*_*kan 3 laravel laravel-8

当阅读这里时,你会发现外墙并不是真正的外墙

为什么 Laravel 的外观表现得像单例?

无论如何,Facades 上的所有方法都是静态的(请自行查看Illuminate\Support\Facades

有些别名实际上就是这样,例如普通类

'Arr' => Illuminate\Support\Arr::class,

它作为门面有什么意义?

Ake*_*rts 7

为什么 Laravel 主要使用 Facades 而不是单例?

由于其实现方式,外观是单例的。

首先,让我们定义一些我们使用的术语:

Facade可以指两件事:

  1. Laravel 的 Facades,一种为开发人员提供方便的工具,也是依赖注入的替代方案
  2. 门面设计模式。Laravel 的 Facades 不是外观设计模式的实现。对于那些刚接触 Laravel 但熟悉外观设计模式的人来说,这是一个常见的困惑点。Laravel 的 Facades 更好地被认为是Laravel 容器内服务的静态代理。

Singleton是一种创建型设计模式,可让您确保类只有一个实例,同时提供对此实例的全局访问点。(来源

这些定义并不相互排斥。某些东西可以是外观单例(它们是否应该两者都是不同的对话)。

Laravel 的 Facade 在两种情况下都是单例:抽象 Facade 类和 Laravel 的 IoC Container。

抽象类- 所有单独 Facade 的父类 - 是 Facade 作为单例Facade主要原因。当 Facade 被调用时,它从 Laravel 的容器解析其底层类并将其保存到本地静态属性。后续调用将引用本地属性值,而不是再次从容器解析。

Laravel 的控制反转容器是 Facade 引用单例对象的另一种方式。将服务绑定到容器时,您可以使用它Container::singleton()来确保服务在检索时始终解析为同一实例。

我希望这能澄清某些东西可以同时是单例外观。

有些别名实际上就是这样,例如普通类

在这种情况下,别名只是对 PHP 的调用class_alias(),并且是通过最小化完全限定的类名(命名空间 + 类名)来使外观和其他类更易于使用的一种方法。use Illuminate\Support\Arr;您无需导入,只需在代码中使用use Arr;或即可。\Arr::get()这在 Blade 模板中特别有用。这些别名对于但不限于外观很有用。

如果所有函数都是静态的,为什么辅助函数都与例如vs config()::set() Config::set()`session()一起使用?->config()->set()when the facade does

只是目的和实现上的不同。Facade 是一个代理 - 所有交互都与 Facade 本身发生,但它代理对底层服务的请求。辅助函数不代理任何调用,它们仅返回从容器检索的服务。

// Only interacts with the Facade class.
// set() is proxied via the magic __callStatic() method.
Config::set();

// config() returns an instance of the Config Repository class.
// Subsequent calls are directly on that instance.
// No magic methods used.
config()->set();
Run Code Online (Sandbox Code Playgroud)

Facades 还附带了一些模拟和测试实用程序,这可能会使它们成为更好的解决方案,具体取决于您的测试需求。