laravel 的服務提供者,是框架的核心,提供了路由、日誌、緩存等功能。這裏要實現的需求是使用第三方 API 獲取天氣狀況,涉及到服務提供者、契約、依賴注入等方面。相關內容能夠經過下方參考資料進行了解,本文內容不進行展開介紹,代碼可查看 GitHub。php
artisan
快捷的建立服務提供者,執行 php artisan make:provider WeatherServiceProvider
即在 app/Providers
目錄下建立了 WeatherServiceProvider.php
文件;config/app.php
中註冊服務提供者,在 providers
數組中將建立的服務提供者 App\Providers\WeatherServiceProvider::class,
寫入,以下
app
目錄下新建 Contracts
目錄用以存放契約文件;app/Contracts
目錄下建立契約,即 Weather.php
接口文件。在接口中只定義了 public function getWeather($cityName);
一個方法用於獲取天氣信息;app
目錄下新建 Service/Weather
目錄用於存放實現 Weather.php
契約的文件;app/Service/Weather/Xinzhi.php
。繼承了 Weather.php
接口文件,全部要實現 getWeather
方法,代碼可查看 GitHub;Xinzhi.php
,另外選擇和風天氣實現契約,文件爲 app/Service/Weather/Hefeng.php
。代碼查看 GitHub;咱們已經實現了契約,接下來就是綁定具體實現類。回到開始建立的服務提供者,在 register
方法中添加以下代碼html
$this->app->bind('App\Contracts\Weather', function() { return new Xinzhi(); });
最後就能夠正常使用了。新建路由,而後測試。試下經過依賴注入調用laravel
public function getWeather(Request $request, Weather $weather) { return $weather->getWeather($request->input('city', 'beijing')); }
沒有問題git
完成上述全部步驟,這個需求已經實現了。看起來很麻煩是吧,徹底能夠封裝一個函數,直接調用就能夠了,沒有必要自定義服務提供者、建立契約。實際上述步驟,其中的一個目的就是小標題那兩個字——解耦。
假設一下,咱們須要在不少代碼中使用這個功能,忽然有一天,這個 API 掛了,怎麼辦?四處去查找、檢查代碼,而後再去修改,同時要注意參數、返回值等。光是聽起來就很煩了。這個時候,若是咱們的代碼按照上述的步驟進行開發,解決方法就大不相同了。簡而言之,一行代碼就能夠搞定。
還記得上面那個伏筆吧,一共有兩個實例實現了接口。將自定義的服務提供者 register
作以下修改github
$this->app->bind('App\Contracts\Weather', function() { // return new Xinzhi(); return new Hefeng(); });
修改了契約的綁定,全部使用 Weather
契約進行依賴注入的實例,都會由 Xinzhi.php
實例切換到 Hefeng.php
實例。數組
契約固然不止解耦這一個做用,代碼更容易理解、更方便維護,甚至能夠當作簡明的開發文檔。更多的深刻理解,請查看下方參考資料。緩存
參考資料:底層原理 —— 服務提供者、底層原理 —— 契約(Contracts)、Laravel 服務容器實例教程 —— 深刻理解控制反轉(IoC)和依賴注入(DI)、 Laravel 從學徒到工匠系列 依賴注入篇。app