重構 Controller
雖然 Controller 昨天切成兩個了,但是裡面還是亂七八糟,今天的目標是要把裡面盡可能的整理。
使用 Service Provider
Shop
與 Mysql
在這個應用程式裡,是屬於單例的角色。我們可以把這兩個物件,放在 Laravel Container 裡,透過 DI 注入讓 Controller 取得,這樣程式會更加簡潔。
首先我們先處理 Mysql
:
// app/Providers/AppServiceProvider.php |
如此在使用 app(Mysql::class)
就能取得到 Mysql
單例物件了。接著在調整 Shop
的建構子:
public function __construct(Mysql $mysql) |
這樣在使用 app(Shop::class)
時,Laravel 會發現要注入 Mysql
物件,所以會接著用 app(Mysql::class)
拿到 Mysql
物件後,再繼續把 Shop 物件建構出來。
Controller 的 Action 也有一樣的功能:當定義 Shop
物件時,Laravel 會使用 app(Shop::class)
取得 Shop
物件再傳入 action:
public function index(Request $request, Shop $shop) |
如此一來,就不需要在 controller 裡面建構 Shop
物件,而能專注在如何操作 Shop
物件。
同理 Smarty 也能做一樣的處理:
$this->app->singleton(Smarty::class, function () { |
完成後,coverage 累積上升 1.98%。
移除 config.php
上面做完之後,會發現 config.php
的內容都是定義常數,因此可以移到 Service Provider 裡的 boot()
方法,接著就能移除它了。
帳號密碼目前的設計也是常數,所以先暫時也用常數處理。
完成後,coverage 累積上升 2.76%。
拆出獨立的 action
如 contact 的功能相對獨立,可以另外拆出一個 Controller 來處理:
class ContactController extends Controller |
調整 Route:
Route::get('/contact', 'ContactController@index'); |
調整 View:
<a href="/contact">聯絡我們</a> |
測試也得調整:
$browser->visit('/contact') |
這樣就能把一個頁面移出另一個 controller 了。
同樣的方法也可以用在 admin 登入頁。
使用 Request
Laravel 的套件 Request
提供了許多取得 HTTP request 的方法,如:
if (!isset($_GET['act'])) { |
可以用下面的程式碼取代:
$act = $request->query('act', 'main'); |
記得要先確認其他程式碼沒有使用到
$_GET['act']
才能直接這樣改。
許多常用的判斷,框架都有提供更精簡的方法提供開發者使用。因此改使用這些方法,也是個提高易讀性的好辦法。
今天的程式可以參考 GitHub PR。
上面的技巧不斷使用後,會發現 coverage 越來越高,程式也會越來越精簡好懂,這正是重構的目的與價值。