PHP Laravel 的 Facade 的理解

栏目: PHP · 发布时间: 5年前

内容简介:在一般情況咱們如果要使用物件的某個方法可能會寫成如下 :但是有時後你會看到如下的程式碼 :而這就是 Laravel 所提供的 Facade 語法糖,而 Facade 實際上是一種設計模式。
PHP Laravel 的 Facade 的理解

什麼是 Laravel Facade ?

在一般情況咱們如果要使用物件的某個方法可能會寫成如下 :

<?php

$userService = $app->make('UserService');
$userService->createUser();

但是有時後你會看到如下的程式碼 :

<?php

UserService::createUser();

而這就是 Laravel 所提供的 Facade 語法糖,而 Facade 實際上是一種設計模式。

Facade(外觀) 設計模式

Facade 設計模式基本的定義如下 :

定義一個高層級的接口,客戶端只能透過它來與子系統進行溝通。

畫成概念圖大概長的如下,客戶端當要使用某個子系統所提供的功能時,不會直接去使用,而是會透過 Facade 來進行操作。

PHP Laravel 的 Facade 的理解

程式碼範例

假設咱們現在有個功能是用使用 LineSDK 來將訊息推送到 Line 取,然後咱們假設 sdk 的程式碼如下。

<?php

interface IMessage 
{
    public function push();
}


class LineSDK implements IMessage 
{
    public function push()
    {
        var_dump('I push a message to line');
    }
}

然後我們這裡會在寫一個 Facade 來讓我們的系統來使用。

<?php
class MessageFacade
{
    private $sdk; 

    public function __construct(IMessage $sdk)
    {
        $this->sdk = $sdk;
    }

    public function push()
    {
        $this->sdk->push();
    }
}

最後這個時候客戶端想要使用時,就會透過 Facade 來進行發送訊息,如下程式碼。

<?php

// 備註,在 laravel 時這裡嚴格來說會寫成
// $app->make('Imessage')
// 而不會看到 linesdk 這東西
$sdk = new MessageFacade(new LineSDK());
$sdk->push();

這樣有什麼好處 ?

當 sdk 進行修改時,你就不需要修改應用層的也方,只要修改 Facade 就好。

但這樣還是要改啊 ? 只是換個地方改而以 ?

那假設你有十個地方直接使用 SDK 呢 ? 那這樣不就代表你十個地方就要改,而如果使用 Facade 就只有一個地方要修改。

Laravel Facade 是如何實現的呢 ?

就單來說,它就如下圖所示,主要的核心就是在 Facade 這個抽象類別,它裡面會定義一個 php__callStatic 方法,它被執行到的時機為,這個類別中被呼叫靜態方法時,他就會被執行到。

PHP Laravel 的 Facade 的理解
<?php

abstract class Facade {
    public static function __callStatic($method, $args)
    {
        $instance = static::getFacadeAccessor();
        return $instance::$method(...$args);
    }
}
<?php

class MessageFacade extends Facade
{
    protected static function getFacadeAccessor(){
        return new LineSDK(); 
    }
}

class LineSDK 
{
    public function push()
    {
        var_dump('I push a message to line');
    }
}
<?php

include 'Facades/MessageFacade.php';

MessageFacade::push();

Laravel Facade 的爭論

它們的爭論點就是 :

是否要使用 Laravel Facade

這裡大至上會分成兩派 :

使用 Laravel Facade

這一派的程式碼會寫的如下 :

<?php
class Log
{
  
    public function __construct()
    {
    }

    public function send(log): void
    {
        LogService::send(log);
    }  
}

不使用 Laravel Facade

而這一派的程式碼會寫的如下 :

<?php

class Log
{
    private ILogService $logService;
  
    public function __construct(ILogService $logService)
    {
      $this->logService = $logService;
    }

    public function send(log): void
    {
      $this->logService->send(log);
    }  
}

支持與反對的看法

首先支持使用 Facade 這一派的他們提出以下使用後的優點 :

  1. 簡潔的程式碼。
  2. 乾淨的建構子。
  3. 更高的可測試性與彈性。

但相對的反對派提出了一下問題 :

  1. 相依了 Facade,這樣事實上就打破了當初建立 container 來想解決的事情。
  2. 要知道這個類別中有使用那些外部套件,那就只能一個一個找。
  3. IDE 的不友好。

順到說一下,就我各人的看法我比較偏向不使用 Laravel Facade,主要是因為我比較在意一個類別的相依性控制,而每當我需要知道這個類別有啥相依時,不用讓我一個一個去慢慢的找,對我來說有點浪費時間。

順到說一下,在下面的參考資料裡包含了大部份吵架的文章,有興趣的人可以去看看。

備註 : 關於使用 Laravel Facade 有更高的可測試性說明

在 Laravel Facade 中,如果你有一段程式碼直接的使用 Laravel Facade 如下 :

<?php

public function getIndex()
{
    Event::fire('foo', ['name' => 'Dayle']);

    return 'All done!';
}

然後你這時要進行測試時,可以使用 shouldReceive 的方法來模擬 Event :

<?php

public function testGetIndex()
{
    Event::shouldReceive('fire')->once()->with('foo', ['name' => 'Dayle']);

    $this->call('GET', '/');
}

參考資料


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

奈飞文化手册

奈飞文化手册

[美] 帕蒂·麦考德 / 范珂 / 浙江教育出版社 / 2018-10-1 / 69

一本对奈飞文化进行深入解读的力作。2009年,奈飞公开发布了一份介绍企业文化的PPT文件,在网上累计下载量超过1500万次,被Facebook的CFO谢丽尔·桑德伯格称为“硅谷重要文件”。本书是奈飞前CHO,PPT的主要创作者之一帕蒂·麦考德对这份PPT文件的深度解读。 本书系统介绍奈飞文化准则,全面颠覆20世纪的管人理念。在这本书中,帕蒂·麦考德归纳出8条奈飞文化准则,从多个角度揭示了奈飞......一起来看看 《奈飞文化手册》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具