Is there any drawback with Laravel's use of fa

2020-07-29 02:00发布

There are some criticism [see below] to the Laravel's extensive use of facade, which seems is an anti-pattern, e.g.

Singleton "facades" only upside is that they are relatively "easy to use", but technical debt introduced from such shortcuts is hard to even estimate.

Sample code:

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

So, using the above example code, can anyone show me how this code can be better written in PHP, if we are not using facades?

4条回答
我欲成王,谁敢阻挡
2楼-- · 2020-07-29 02:40

Since you've tagged unit testing, you should keep in mind that static access facades like Laravel's ones make it very hard to accomplish the Isolation principle of unitary tests.

It is impossible (as far as I know) to stub or mock an static-accessed class or method, because you need to be nominative about it.

Another problem you might get is if you need to change the way your application does caching. While you are able to rely solely on Laravel, that's fine, but in the moment you need it to change, you will have to seek for all Cache::get('key') occurrences in order to refactor.

As @lukasgeiter pointed, a better approach would be to use Dependency Injection, through a Dependency Injection Container, such as Pimple.

查看更多
对你真心纯属浪费
3楼-- · 2020-07-29 02:42

I think Laravel does facades right in that they are really just aliases for classes which are actually proxies for resolving the underlying classes from the IoC container. This alleviates most of the problems when trying to test code which may use them. Resolving them from the IoC container yourself is really just doing what Laravel is already doing under the hood while in my opinion sacrificing readability of your code.

In the case of testing, the facades can easily be mocked with Cache::shouldReceive('someFunction')->...

From a design standpoint, you can swap implementations by modifying the service provider so that your implementation is chosen over the default one when resolving from the IoC container using the facade. That should give you the same advantages as dependency injection would give you while maintaining readability of your code.

I think the main issue here is that these aren't facades in their traditional sense and this causes a lot of confusion.

查看更多
等我变得足够好
4楼-- · 2020-07-29 02:45
$app['cache']->get('key');

Do you ever plan on moving your Laravel code-base outside of the Laravel Framework? If not, disregard these comments in my opinion, because that is the only noteworthy disadvantage of Facades.

But if you want to continue down that path, this article has an example that may help you. http://programmingarehard.com/2014/01/11/stop-using-facades.html

查看更多
Explosion°爆炸
5楼-- · 2020-07-29 02:52

Disclaimer: I don't necessarily agree that facades are bad or an anti-pattern

A "better" way to do this would be using dependency injection. For example if this is your controller:

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

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

Or you can do the same for just one method:

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

Note that we're not type hinting the facade class here but the underlying framework class. You can find a list of these classes in the docs.

查看更多
登录 后发表回答