laravel - 为什么 laravel 主要使用 Facades 而不是单例?
问题描述
在这里阅读时,您会发现外墙并不是真正的外墙
无论如何,Facades 上的所有方法都是静态的(去看看你自己Illuminate\Support\Facades
)
有些别名实际上就是这样,例如普通类
'Arr' => Illuminate\Support\Arr::class,
它是外墙有什么意义?
解决方案
为什么 laravel 主要使用 Facades 而不是单例?
Facades 是单例的,因为它们的实现方式。
首先,让我们定义一些我们正在使用的术语:
Facade
可以参考两件事:
- Laravel 的 Facades,一种用于方便开发人员的工具,也是依赖注入的替代方案
- 立面设计模式。Laravel 的 Facades不是外观设计模式的实现。对于那些刚接触 Laravel 但熟悉外观设计模式的人来说,这是一个常见的困惑点。Laravel 的 Facades 最好被认为是Laravel 容器中服务的静态代理。
Singleton
是一种创建型设计模式,可让您确保一个类只有一个实例,同时提供对该实例的全局访问点。(来源)
这些定义并不相互排斥。某些东西可以是外观和单例(它们是否应该是不同的对话)。
Laravel 的 Facade 有两种方式是单例:抽象 Facade 类和 Laravel 的 IoC Container。
抽象Facade
类——所有单个 Facade的父级——是 Facade 充当单例的主要原因。当调用 Facade 时,它会从 Laravel 的容器中解析其底层类并将其保存到本地静态属性中。后续调用将引用本地属性值,而不是再次从容器中解析。
Laravel 的 Inversion of Control Container是 Facade 可以引用单例对象的另一种方式。当您将服务绑定到容器时,您可以使用它Container::singleton()
来确保服务在检索时始终解析为相同的实例。
我希望澄清一些东西可以同时是单例和外观。
有些别名实际上就是这样,例如普通类
在这种情况下,别名只是对 PHP 的调用class_alias()
,是一种通过最小化完全限定的类名(命名空间 + 类名)来使 Facades 和其他类更易于使用的方法。而不是需要use Illuminate\Support\Arr;
,您可以只use Arr;
或\Arr::get()
在您的代码中不导入。这在 Blade 模板中特别有用。这些别名可用于但不限于 Facades。
如果所有函数都是静态的,为什么所有的辅助函数
session()
都使用->
例如config()->set()
vs config()::set()when the facade does
Config::set()`?
只是目的和实施的不同。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();
Facades 还带有一些模拟和测试实用程序,这可能会使它们成为更好的解决方案,具体取决于您的测试需求。
推荐阅读
- generics - 对于任何泛型类型参数 T,如何使 Fn(T) + 'static 注册为 'static?
- c++ - 可以将类对象创建为仅左值吗?
- ruby-on-rails-5 - 未经授权的连接尝试被 Rails 5 ActionCable 拒绝
- java - Parse Int 使我的程序崩溃,是的,我将 xml iput 类型设置为 number
- javascript - jQuery 与 doctype 声明之前输出的文本进行交互
- python - 如何使用 For 循环一次选择一行
- javascript - Angular 推送到 Django 以获取用户登录表单错误“SyntaxError: Unexpected token < in JSON at position 2 at JSON.parse (
)" - c# - 从 C# 桌面应用程序中获取 Arduino Uno 控制器的唯一标识值
- php - 无法使用 $_SERVER 变量卷曲到 PHP 页面
- c++ - 如何惯用地编写 const 迭代器?