這麼多天以來,看了很多 Laravel 的程式,其實可以發現它有一些常見的模式。沒有好壞,只是一種可參考的寫法:
if ($user = $this->resloveUser()) {
$user->can('create');
}
這樣寫可以省一行定義,但 if 內的事務過於複雜就容易不知道 condition 的副作用為何。
if (method_exists($middleware, 'handle')) {
return $middleware->handle();
}
曾有討論是反對這種寫法,因為會覺得直接定介面就好。但反過來說,如果定了介面,就無法改變參數的定義,如果想設計一個可長可短,同時要能自動注入的方法,就是件不可能的任務了:
public function handle($request, $next);
public function handle($request, $next, $arg1);
public function handle($request, $next, $arg1, $arg2);
protected function getRouteForMethods($request, array $methods)
{
// ...
$this->methodNotAllowed($methods);
}
protected function methodNotAllowed(array $others)
{
throw new MethodNotAllowedHttpException($others);
}
通常要對同一個物件做操作,且前後操作是有相關聯的時候,使用 fluent pattern 更能感受到程式所想表達的意圖:
Gate::allows('update-post', $post));
Gate::forUser($user)->allows('update-post', $post));
流程控制區塊指的是 if / for / foreach / while 等。這些流程都與循環複雜度呈正相關。如果越大,代表這段程式越難懂,也越容易出現 bug。目前有注意最多的地方在 Container,有七個流程控制。
比起下面兩種寫法,會是上面比較好懂一點。當流程控制區塊越多的時候,將會更明顯。
if (!$user) {
return false;
}
if (!is_callable($callback)) {
return false;
}
return $callback($user);
另一種相反的寫法
if ($user) {
if (is_callable($callback)) {
return $callback($user);
}
}
return false;
筆者時常說:
程式語言也是一種「語言」,跟自然語言有其相像的點。
這次的主題是分析原始碼,同時就有點像在做一個翻譯員,試圖自己了解,也讓各位讀者也能理解程式所想表達的意圖。
有趣的是,這過程就很像在讀小說會感受到文學的美一樣,會覺得程式這樣寫很好理解,甚至很酷。到了自己要寫文章--也就是要寫程式時,就會回頭把酷炫的寫法「借」過來使用,同時也想讓更多人除了使用外,也能了解自己所寫的程式。
而更重要的,程式開發人員,最強大的地方在於,有能力可以理解與分析其他人寫的原始碼。分析原始碼,正是在培養工程師閱讀程式的能力。另外也增加判斷程式好壞能力的好方法,因為唯有同時看過好程式與爛程式,才有可能會知道什麼樣的程式是好的。
這三十天寫的分析,筆者盡可能寫出讓其他開發者能理解的描述,希望能幫助到大家。
漏了一個括號
v 要補一個括號
if ($user = $this->resloveUser() {
$user->can('create');
}
真的漏了,感謝提醒