【问题标题】:Is there any drawback with Laravel's use of facades?Laravel 使用门面有什么缺点吗?
【发布时间】:2015-04-10 17:24:59
【问题描述】:

对于 Laravel 大量使用外观有一些批评 [见下文],这似乎是一种反模式,例如

单例“立面”唯一的好处是它们相对“易于 使用”,但这种快捷方式引入的技术债务很难 甚至估计。

示例代码:

$value = Cache::get('key');

那么,使用上面的示例代码,如果我们不使用外观,谁能告诉我如何更好地用 PHP 编写这段代码?

【问题讨论】:

  • 引用的批评来自哪里?

标签: php unit-testing laravel design-patterns laravel-5


【解决方案1】:

免责声明:我不一定同意外观是不好的或反模式

一个“更好”的方法是使用dependency injection。例如,如果这是您的控制器:

public function __construct(\Illuminate\Cache\Repository $cache){
    $this->cache = $cache;
}

public function doSomething(){
    $value = $this->cache->get('key');
}

或者您可以只对一种方法执行相同的操作:

public function doSomething(\Illuminate\Cache\Repository $cache){
    $value = $cache->get('key');
}

请注意,我们在这里不是类型提示外观类,而是底层框架类。你可以找到这些类的列表in the docs

【讨论】:

    【解决方案2】:
    $app['cache']->get('key');
    

    你有没有打算将你的 Laravel 代码库移到 Laravel 框架之外?如果不是,在我看来,请忽略这些 cmets,因为这是 Facades 唯一值得注意的缺点。

    但是,如果您想继续走这条路,本文提供的示例可能会对您有所帮助。 http://programmingarehard.com/2014/01/11/stop-using-facades.html

    【讨论】:

    • 是的。我提供的链接显示了您的操作方式。我的是从 Taylor 关于该主题的一篇帖子中复制而来的
    【解决方案3】:

    我认为 Laravel 的外观是正确的,因为它们实际上只是类的别名,实际上是从 IoC 容器解析底层类的代理。当尝试测试可能使用它们的代码时,这可以缓解大多数问题。自己从 IoC 容器中解析它们实际上只是在做 Laravel 已经在做的事情,而在我看来会牺牲代码的可读性。

    在测试的情况下,可以很容易地用Cache::shouldReceive('someFunction')->...模拟外观

    从设计的角度来看,您可以通过修改服务提供者来交换实现,以便在使用外观从 IoC 容器解析时选择您的实现而不是默认实现。这应该会给您带来与依赖注入相同的优势,同时保持代码的可读性。

    我认为这里的主要问题是这些不是传统意义上的门面,这会引起很多混乱。

    【讨论】:

      【解决方案4】:

      既然你已经标记了单元测试,你应该记住,像 Laravel 的静态访问门面使得实现单元测试的隔离原则变得非常困难。

      (据我所知)存根或模拟静态访问的类或方法是不可能的,因为您需要对它进行主格操作。

      如果您需要更改应用程序的缓存方式,您可能会遇到的另一个问题。虽然您可以完全依赖 Laravel,但这很好,但是当您需要更改它时,您将不得不寻找所有出现的 Cache::get('key') 以进行重构。

      正如@lukasgeiter 指出的那样,更好的方法是通过依赖注入容器使用依赖注入,例如Pimple

      【讨论】:

      • 既然 OP 使用的是 Laravel,他还不如只使用 Laravel IoC 容器。实际上,如果你只是输入提示依赖项,Laravel 会自动为所有由它解析的类注入它们。最重要的是,所有控制器都是如此。
      猜你喜欢
      • 2016-02-23
      • 1970-01-01
      • 2010-09-27
      • 2011-04-26
      • 2011-02-28
      • 2016-08-28
      • 2020-08-07
      • 2014-10-04
      • 1970-01-01
      相关资源
      最近更新 更多