Laravel Facade and Contract

Facades

Laravel 提供的 Facade 是 Facade pattern。實作上利用 static function 把 Laravel 的功能包起來,可以在使用的時候更簡潔。Laravel 在 Facade 做些 function 讓測試時可以假造 Facade class 的結果,因此雖然是 static function 卻仍擁有可測試性。

使用 Facade 要注意以下兩點:

  • class 的大小。
    • Facade 依然是 class 的 dependency,使用 Facade 不會讓 dependency 顯現在 constructor,就不容易看得出 class 長得太大。
    • 這跟設計有關,只要設計 ok,當然可以用 Facade
  • 做與 Laravel 互動的 third party package 時,不適合用 Facade,應該要走一般 DI。
    • 因為 third party package 本身沒有 Laravel framework,無法是用 Laravel Facade 提供的 test 能力。

Contracts

Laravel 的 Contracts 是一堆定義 framework 提供的 core service 的 interface。所有 Laravel 的 contract 有他們自己的 Github repo,寫 package 時可以只使用其中幾個 contract。

Contracts vs Facades

每個 facade 都有對應的 contract。contract 跟 facade 是可以達到同樣事情的不同寫法或做法。

如果喜歡在 constructor explicit 的寫出一個 class 的 dependency,就用 contract。

一般來說,偏好使用 contract 還是 facade 對 application 而言沒有太大差別。但是 package 用 contract 會比較好,因為對 package 來說 contract 比較好測。

何時使用 Contracts

用 facade 還是用 contract 基本上是偏好問題。

有設計好 class 的責任,用 facade 跟 contract 沒太大差別。

用 contracts 的原因:loose coupling 跟 simplicity

Loose Coupling

contracts package 沒有任何 implementation 也沒有 dependency,所以 depend on 它不會被任何 library 或 framework 綁住,反而可以利用定義好的 interface,底下實作可以任意抽換。

Simplicity

定義良好的 interface 可以很容易看出 laravel 提供的功能。

比起依賴於複雜又龐大的 class,依賴於定義良好的 interface,code 比較好懂。

如何使用 Contracts

在 type hint 寫 contract 的名字,service container 會進行 resolve 並且 inject 適當的 instance。

Reference