假面模式Facade的實現基於
Illuminate\Support\Facades\Facade;
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot();
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
return $instance->$method(...$args);
}
這個方法。相當於在物件外邊封裝了一個方便訪問的殼子。那這個殼子對應的物件是同一個嗎?
重點在於Facade的如下方法:
protected static function resolveFacadeInstance($name)
{
if (is_object($name)) {
return $name;
}
if (isset(static::$resolvedInstance[$name])) {
return static::$resolvedInstance[$name];
}
if (static::$app) {
return static::$resolvedInstance[$name] = static::$app[$name];
}
}
通過殼子呼叫方法,第一步會去尋找對應的物件,尋找分兩種情況:
- 如果getFacadeAccessor返回的是直接new一個物件,那麼每次獲取到的物件都不一樣。
- 如果返回的是一個在AppServiceProvider裡面bind、singleton過得abstract,那麼這個方法會快取物件,所以每次獲取都是同一個物件。而不論你用的是bind,還singleton。
如何能根據bind、singleton自動判別是應該全域性唯一,還是每次變化,可以直接複寫這個方法
protected static function resolveFacadeInstance($name)
{
return static::$app[$name];
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結