寫一個簡單的 Facade 示例

zhaiduting發表於2019-11-03

首先在API名稱空間裡寫個DB類

namespace API{
    class DB{
        public function __construct(){
            echo __CLASS__.'::'.__FUNCTION__.'<br><br>';
        }
        public function Write($str){
            echo __CLASS__.'::'.__FUNCTION__."($str)<br><br>";
        }
        public function Read($str){
            echo __CLASS__.'::'.__FUNCTION__."($str)<br><br>";
        }
        public function __call($method, $str){
            echo "根本就沒有這個方法: $method($str[0]) <br><br>";
        }
    }
}

接著新增如下這段程式碼

namespace {
    abstract class Facade{
        public static function getInstance($classname){
            echo __CLASS__.'::'.__FUNCTION__.'例項化物件<br>';
            return new $classname();
        }

        abstract public static function getFacadeAccessor();

        public static function __callstatic($method,$arg){
            echo __CLASS__.'::'.__FUNCTION__.' 靜態魔術方法被觸發<br>';
            $accessor= static::getFacadeAccessor();
            $instance= static::getInstance($accessor);
            return call_user_func_array(array($instance, $method), $arg);
        }
    }

    class DBFacade extends Facade{
        public static function getFacadeAccessor(){
            echo __CLASS__.'::'.__FUNCTION__.',返回值='.API\DB::class.'<br>';
            return API\DB::class;
        }
    }
}

再新增實際呼叫程式碼

namespace {
    DBFacade::Write('張三');
    DBFacade::Read('李四');
    DBFacade::Ohno(2);
}

執行效果如截圖
寫一個簡單的 Facade 示例
本例涉及基本知識點如下
1、名稱空間的大括號寫法;
2、魔術常量__CLASS____FUNCTION__的用法;
3、魔術方法__call()的用法;
4、靜態魔術方法__callstatic()的用法;
5、call_user_func_array()的用法;
6、延遲靜態繫結static::關鍵字的用法(重點)

就本例而言,static::getFacadeAccessor首先在子類中查詢getFacadeAccessor()方法,並且找到了,於是呼叫子類方法;對於static::getInstance也是同理,但是子類中並沒有這個方法,於是呼叫了當前類的getInstance()方法。

相關文章