クリーナーコードのガード節を使用する


Guard節はコードをクリーンアップするための超簡単な方法を提供する気の利いたパターンです.それらの主な機能はコードのブロックを初期化することです.
あまりにも頻繁に、if文に包まれたメソッド全体の本体が見えます.コードが別のレベルにインデントされるたびに、コードを読んでいる間、あなたは精神的に追跡されなければならないコンテクストのもう一つの部分を加えています.
パターンを使わない簡単な関数を見てみましょう.
function update($contact, $data) {
  if (valid($data)) {
    $contact->update($data);
  }
}
このような単純な例では、大したことではないかもしれません(おそらくそうではないかもしれません).
function update($contact, $data) {
  if (! valid($data)) {
    return;
  }

  $contact->update($data);
}
これがガード条項の本質である.インデントを減らすことは、複雑さと不必要な文脈を減らして、機能が何をするつもりであるかの可視性を増やします.
それがどこで輝くかについて、本当に見るために、コードのより複雑な部分に正しくなりましょう.
if (! is_null($subscribed)) {
    if ($email = $contact->email) {
        $updated = Contact::query()
            ->where('email', $email)
            ->where('is_subscribed', ! $subscribed)
            ->update([
                'is_subscribed' => $subscribed,
            ]);

        if ($updated) {
            if ($subscribed) {
                event(new Subscribed($email));
            } else {
                event(new Unsubscribed($email));
            }
        }
    }
}
Guard句については何が素晴らしいですか.ここでコードを取ることができます.ここでは、ある文では文が深くなったときに4を得、それを単一のインデントに減らします.
これを行う手順は簡単です.
  • Ifステートメントを逆にして逆の状態をチェックします.
  • コードの残りの前にif文を終了します.
  • 繰り返します.これが実行可能でない唯一の時間は、ifが他のものを持っているか、またはElseifがある場合です.
    一度に一歩を見ましょう.まず、最初の行でif文を取り、それをガード節にします.
    if (is_null($subscribed)) {
        return;
    }
    
    if ($email = $contact->email) {
        $updated = Contact::query()
            ->where('email', $email)
            ->where('is_subscribed', ! $subscribed)
            ->update([
                'is_subscribed' => $subscribed,
            ]);
    
        if ($updated) {
            if ($subscribed) {
                event(new Subscribed($email));
            } else {
                event(new Unsubscribed($email));
            }
        }
    }
    
    returnがNULLでないときに続けるのではなく、NULLのときに終了します.精神的に、私たちは今、この情報を捨てることができるので、コードが何をしているかに焦点を当てることができます.しかし、もう一度、我々の新しいGuard条項の後のコードは、完全にif声明で包まれます.その過程を繰り返しましょう.
    if (is_null($subscribed)) {
        return;
    }
    
    if (! ($email = $contact->email)) {
        return;
    }
    
    $updated = Contact::query()
        ->where('email', $email)
        ->where('is_subscribed', ! $subscribed)
        ->update([
            'is_subscribed' => $subscribed,
        ]);
    
    if ($updated) {
        if ($subscribed) {
            event(new Subscribed($email));
        } else {
            event(new Unsubscribed($email));
        }
    }
    
    我々は、インデントの別のレベルを削減しました!今連絡先がメールを持っていない場合は、我々はそれらを購読しません.終了.私たちは、この機能が実際に達成されているものの中心になり、エッジケースが何であるかに焦点を当てています.とても読みやすい.
    上記の行16 ( $subscribed )を見ると、一つのif文の中に別のコードが表示されます.あなたはそれを推測しました.
    if (is_null($subscribed)) {
        return;
    }
    
    if (! ($email = $contact->email)) {
        return;
    }
    
    $updated = Contact::query()
        ->where('email', $email)
        ->where('is_subscribed', ! $subscribed)
        ->update([
            'is_subscribed' => $subscribed,
        ]);
    
    if (! $updated) {
        return;
    }
    
    // a little extra sugar for fun ;)
    $event = $subscribed ? Subscribed::class : Unsubscribed::class;
    $event::dispatch($email);
    
    それを見てください.私たちは完全に4 xインデントブロックのコードを1つのインデントに減らしました.私の意見では、我々の結果ははるかに読みやすい.
    私はこのパターンを発見以来、私はそれにリファクタリングまたはそれを使用して場所を発見した.
    私はあなたがそれとして役に立つと思います.グッドラック!