解读Laravel,看PHP如何实现Facade?
2017-06-17 11:16
211 查看
4000
刚刚开始学Laravel就会接触到路由
后来笔者一本正经的去读过Route类的代码,惊讶的发现并没有get这个方法,之后了解到Laravel用了Facade模式。
Facade本质上是一个“把工作推给别人做的”的类。
Facade存在的价值,可以从服务容器谈起。服务容器,可见我的另一篇博文,地址:http://www.cnblogs.com/sweng/p/6430374.html
举个例子,不知道大家以前写代码有没有过obj->method(arg1,arg2)->func(arg3,arg4);的体验。学过服务容器的读者知道,这行代码就是把服务容器里的对象取出来,并调用他的方法。这对熟悉服务容器里注册过哪些类的开发人员来说,这种代码还是可以接受的。但是如果像路由定义那样,也要写成这样冗长的形式,实在太不优雅了。所以用Facade模式可以很好的精简代码长度。
我们先写一个DB类
数据库读写是整个系统非常常用的操作。但是DB类会注册在服务容器里,每次数据库读写都要把DB类的对象从服务容器里取出,实在很不方便。
我们写一个Facade类
要理解这个类,我们只要关注最后一个函数,就是__callstatic魔术方法。这个方法就是Facade类型对象在调用他自身没有定义过的函数时,就会调用__callstatic方法,是一个“候选人”的角色。
我们再定义一个DBFacade类
每一个Facade子类都要实现getFacadeAccessor方法,返回只是一个类名字符串,用来代入getInstance方法,来创建一个真正“做事情”的类。
此时,Facade已经可以用了,我们调用DBFacade的静态方法
阅读代码,我们发现,其实DBFacade是没有Write方法的,于是就调用他父类Facade的__callstatic魔术方法,魔术方法我们已经在父类里面实现了。
以前听过同行抱怨,PHP语法乱,难记。但实际上像魔术方法把Facade实现的非常简洁,可见语法设计的精妙。
刚刚开始学Laravel就会接触到路由
1 2 3 | Route::get( '/' , function () { return view( 'welcome' ); }); |
Facade本质上是一个“把工作推给别人做的”的类。
Facade存在的价值,可以从服务容器谈起。服务容器,可见我的另一篇博文,地址:http://www.cnblogs.com/sweng/p/6430374.html
举个例子,不知道大家以前写代码有没有过obj->method(arg1,arg2)->func(arg3,arg4);的体验。学过服务容器的读者知道,这行代码就是把服务容器里的对象取出来,并调用他的方法。这对熟悉服务容器里注册过哪些类的开发人员来说,这种代码还是可以接受的。但是如果像路由定义那样,也要写成这样冗长的形式,实在太不优雅了。所以用Facade模式可以很好的精简代码长度。
我们先写一个DB类
1 2 3 4 5 6 7 8 9 10 11 12 | namespace API; class DB{ public function __construct( $args ){ } public function Write( $str ){ echo 'Write:' . $str .PHP_EOL; } public function Read( $str ){ echo 'Read:' . $str .PHP_EOL; } } |
我们写一个Facade类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Facade{ public function __construct(){ // } public static function getInstance( $classname , $args ){ return new $classname ( $args ); } public static function getFacadeAccessor(){ // } public static function __callstatic( $method , $arg ){ $instance = static ::getInstance( static ::getFacadeAccessor(),[1,2,3]); return call_user_func_array( array ( $instance , $method ), $arg ); } } |
我们再定义一个DBFacade类
1 2 3 4 5 | class DBFacade extends Facade{ public static function getFacadeAccessor(){ return API\DB:: class ; } } |
此时,Facade已经可以用了,我们调用DBFacade的静态方法
1 | DBFacade::Write( 'hello' ); |
以前听过同行抱怨,PHP语法乱,难记。但实际上像魔术方法把Facade实现的非常简洁,可见语法设计的精妙。
相关文章推荐
- 解读Laravel,看PHP如何实现Facade?
- 解读Laravel,看PHP如何实现Facade?
- 解读Laravel,看PHP如何实现Facade?
- PHP 如何实现异步
- PHP中如何配置smarty框架实现PHP代码和HTML代码分离
- 如何使用PHP实现文件上传
- php实现文件上传到指定文件夹,文件路径或名字存入数据库,如何实现啊
- 一看就懂系列之 如何实现与控制php常驻进程
- PHP 单例模式优点意义及如何实现
- PHP 在linux环境下实现多进程,如何子类不产生defunct
- 如何使用php实现评委评分器
- sso单点登录的PHP实现(Laravel框架)
- SSO单点登录的PHP实现方法(Laravel框架)
- 看PHP 如何实现变色验证码
- 如何用php实现定时执行
- 探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
- php如何实现递归遍历文件目录?
- 如何使用PHP实现javascript的escape和unescape函数
- PHP如何实现订单的延时处理详解
- 分析PHP内核中是如何实现 empty, isset 这些函数的