Laravel使用外墙有任何缺点吗?

时间:2015-04-10 17:24:59

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

对Laravel广泛使用的外观存在一些批评[见下文],这似乎是一种反模式,例如。

  单身“外墙”唯一的优势在于它们相对“容易”   使用“,但从这种快捷方式引入的技术债务很难   甚至估计。

示例代码:

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

所以,使用上面的示例代码,如果我们不使用外观,任何人都可以告诉我如何用PHP编写这些代码吗?

4 个答案:

答案 0 :(得分:6)

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

“更好”的方法是使用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

答案 1 :(得分:2)

$app['cache']->get('key');

您是否计划在Laravel框架之外移动Laravel代码库?如果没有,请在我看来忽视这些评论,因为这是Facades唯一值得注意的缺点。

但是如果你想继续沿着这条路走下去,那么本文就有一个可以帮助你的例子。 http://programmingarehard.com/2014/01/11/stop-using-facades.html

答案 2 :(得分:2)

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

在测试的情况下,可以使用Cache::shouldReceive('someFunction')->...

轻松模拟外墙

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

我认为这里的主要问题是传统意义上的这些不是外观,这会导致很多混乱。

答案 3 :(得分:1)

由于您已经标记了单元测试,因此您应该记住,像Laravel这样的静态访问外墙使得完成单一测试的隔离原则非常困难。

存根或模拟静态访问的类或方法是不可能的(据我所知),因为你需要为它提名。

您可能遇到的另一个问题是,您是否需要更改应用程序缓存的方式。虽然你可以完全依赖Laravel,但这很好,但是在你需要改变的那一刻,你将不得不寻求所有Cache::get('key')次出现才能重构。

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