zoukankan      html  css  js  c++  java
  • 解读Laravel,看PHP如何实现Facade?

    刚刚开始学Laravel就会接触到路由

    Route::get('/', function () {
    	return view('welcome');
    });
    

    后来笔者一本正经的去读过Route类的代码,惊讶的发现并没有get这个方法,之后了解到Laravel用了Facade模式。

    Facade本质上是一个“把工作推给别人做的”的类。

    Facade存在的价值,可以从服务容器谈起。服务容器,可见我的另一篇博文,地址:http://www.cnblogs.com/sweng/p/6430374.html

    举个例子,不知道大家以前写代码有没有过obj->method(arg1,arg2)->func(arg3,arg4);的体验。学过服务容器的读者知道,这行代码就是把服务容器里的对象取出来,并调用他的方法。这对熟悉服务容器里注册过哪些类的开发人员来说,这种代码还是可以接受的。但是如果像路由定义那样,也要写成这样冗长的形式,实在太不优雅了。所以用Facade模式可以很好的精简代码长度。

    我们先写一个DB类

    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;
    	}
    }
    

    数据库读写是整个系统非常常用的操作。但是DB类会注册在服务容器里,每次数据库读写都要把DB类的对象从服务容器里取出,实在很不方便。

    我们写一个Facade类

    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);
    	}
    }
    

    要理解这个类,我们只要关注最后一个函数,就是__callstatic魔术方法。这个方法就是Facade类型对象在调用他自身没有定义过的函数时,就会调用__callstatic方法,是一个“候选人”的角色。

    我们再定义一个DBFacade类

    class DBFacade extends Facade{
    	public static function getFacadeAccessor(){
    		return APIDB::class;
    	}
    }
    

    每一个Facade子类都要实现getFacadeAccessor方法,返回只是一个类名字符串,用来代入getInstance方法,来创建一个真正“做事情”的类。

    此时,Facade已经可以用了,我们调用DBFacade的静态方法

    DBFacade::Write('hello');
    

    阅读代码,我们发现,其实DBFacade是没有Write方法的,于是就调用他父类Facade的__callstatic魔术方法,魔术方法我们已经在父类里面实现了。

    以前听过同行抱怨,PHP语法乱,难记。但实际上像魔术方法把Facade实现的非常简洁,可见语法设计的精妙。

    本文为博主原创文章,转载请在明显位置注明出处: http://www.cnblogs.com/sweng

    本作品采用知识共享署名-非商业性使用-禁止演绎 3.0 未本地化版本许可协议进行许可。

  • 相关阅读:
    虚函数和纯虚函数
    MS CRM 2011中PartyList类型字段的实例化
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(4)
    MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(2)
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第二部分)——IOrganizationService(二)
    MS CRM 2011 SDK 5.08已经发布
    MS CRM 2011 Q2的一些更新
    最近很忙
    Microsoft Dynamics CRM 2011最近的一些更新
    补一篇,Update Rollup 12 终于发布了
  • 原文地址:https://www.cnblogs.com/sweng/p/6583005.html
Copyright © 2011-2022 走看看