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

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

    1
    2
    3
    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类

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

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

    我们写一个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);
        }
    }

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

    我们再定义一个DBFacade类

    1
    2
    3
    4
    5
    class DBFacade extends Facade{
        public static function getFacadeAccessor(){
            return APIDB::class;
        }
    }

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

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

    1 DBFacade::Write('hello');

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

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

  • 相关阅读:
    Spring Tool Suite 配置和使用
    自动提示在线/离线状态
    Excel数据导入数据库的SQL快速生成
    MySQL查询和删除重复数据
    内存不足时,调用ajax报的错
    订单支付成功后存储过程
    下订单存储过程
    课程表,订单表(统计报名人数),评论表(统计评论的人数),点赞表(点赞人数)
    更改浏览器的滚动条样式
    自定义文本选中样式
  • 原文地址:https://www.cnblogs.com/wuyuxin/p/7039693.html
Copyright © 2011-2022 走看看