理解 laravel 的Facade

接触Laravel一段时间,对它的一些操作的原理比较感兴趣,比如”Cache::get(‘a’,’b’)”。

这短短的一条语句背后,Laravel进行了哪些工作,让它变成现实呢?今天,我特地研究了一下它的工作原理。理解了这些原理之后,我们也可以实现自己的”Facade”。

要想操作Cache的get方法,必须先有Cache这个类。那么这个类从哪来呢?打开项目app/config/app.php可以看到有一个aliase数组,这里定义了一些框架自带类的别名。我们可以看到,调用Cache类,其实是调用了Illuminate\Support\Facades\Cache这个类。

给类定义别名,可以使用class_alias这个函数:

来看看Illuminate\Support\Facades\Cache这个类是如何定义的:

有没有发现这个类里根本没有’get’这个方法?这到底是怎么回事?这就引出了今天的主题–Facde。

可以看到,Cache类继承了Facade类。Facade其实是一个“静态代理(static proxy)”,它并不提供具体的操作方法,而是实例化一个真正具有该方法的对象,并调用这个方法。我们不妨打开Facade类的定义文件看看:

既然Cache类没有get这个方法,Facade必然得实现__callStatic方法。__callStatic方法很简单–获取对象、调用对象的相应方法。而Cache类实现的getFacadeAccessor方法只不过是告诉Facade应该去获取哪个对象。

所以看到这里,我们可以试着写一个自己的Facade

看到这里,你应该明白Facade到底是怎么回事了吧?那么使用Facade有什么好处呢?在Laravel里,Facade其实是和IOC联合发挥威力的,我们这里单独讨论Facade。

以我目前粗浅的理解,能感受到的好处有:

1.语句更简短。不需要非得new一个对象出来再执行。

2.解除调用对象的强依赖关系。当我们执行Cache::set()的方法时,并不需要关心具体是哪个后端的类真正做了set这个操作。如果将来想把缓存从文件改到redis里,只需要在配置文件里修改一下,业务代码完全不受影响。

 

参考内容:

1.官方文档