リファクタリング
14-1

ネストを早期 return でほぐす

リファクタリングの第一歩は、いきなり構造を変えることではなく「読める形」に整えること。仕様追加のたびに if の内側へ条件を足してきたコードは、本処理と却下理由が遠く離れて対応関係を追えなくなる。条件を反転して「成立しないなら即座に抜ける」形に1段ずつ直すと、挙動を変えずに見通しだけが良くなる。

蔵書ライブラリの貸出登録(リファクタリング前)

Bad

貸出できる条件を if で重ねたため、エラーの理由が対応する条件から画面の反対側まで離れている

条件と else が離れたネスト構造
def register_loan(member: Member, book: Book) -> LoanRecord:
    if member.is_active:
        if book.in_stock:
            if len(member.loans) < LOAN_LIMIT:
                return LoanRecord(
                    member_id=member.id,
                    book_id=book.id,
                    due_date=date.today() + LOAN_PERIOD,
                )
            else:
                raise LoanError("同時貸出の上限に達しています")
        else:
            raise LoanError("この蔵書は貸出中です")
    else:
        raise LoanError("利用停止中の会員です")
Good

条件を反転してガード節に。却下理由が条件の真横に並び、貸出登録の本処理が最後に1つだけ残る

早期 return(ここでは早期 raise)でフラット化
def register_loan(member: Member, book: Book) -> LoanRecord:
    if not member.is_active:
        raise LoanError("利用停止中の会員です")
    if not book.in_stock:
        raise LoanError("この蔵書は貸出中です")
    if len(member.loans) >= LOAN_LIMIT:
        raise LoanError("同時貸出の上限に達しています")

    return LoanRecord(
        member_id=member.id,
        book_id=book.id,
        due_date=date.today() + LOAN_PERIOD,
    )

技法そのものは第6章の早期 return と同じだが、リファクタリングで大事なのは進め方。一番外側の if から1段ずつ反転し、そのたびにテストを回して挙動が変わっていないことを確かめる。一気に書き換えると、どこで壊したか分からなくなる。

参考: 『良いコード/悪いコードで学ぶ設計入門』(ミノ駆動 著、技術評論社)第14章。コード例は原則を自分の題材で表現し直したオリジナル。
14-1

ネストを早期 return でほぐす

リファクタリングの第一歩は、いきなり構造を変えることではなく「読める形」に整えること。仕様追加のたびに if の内側へ条件を足してきたコードは、本処理と却下理由が遠く離れて対応関係を追えなくなる。条件を反転して「成立しないなら即座に抜ける」形に1段ずつ直すと、挙動を変えずに見通しだけが良くなる。

蔵書ライブラリの貸出登録(リファクタリング前)

Bad

貸出できる条件を if で重ねたため、エラーの理由が対応する条件から画面の反対側まで離れている

条件と else が離れたネスト構造
def register_loan(member: Member, book: Book) -> LoanRecord:
    if member.is_active:
        if book.in_stock:
            if len(member.loans) < LOAN_LIMIT:
                return LoanRecord(
                    member_id=member.id,
                    book_id=book.id,
                    due_date=date.today() + LOAN_PERIOD,
                )
            else:
                raise LoanError("同時貸出の上限に達しています")
        else:
            raise LoanError("この蔵書は貸出中です")
    else:
        raise LoanError("利用停止中の会員です")
Good

条件を反転してガード節に。却下理由が条件の真横に並び、貸出登録の本処理が最後に1つだけ残る

早期 return(ここでは早期 raise)でフラット化
def register_loan(member: Member, book: Book) -> LoanRecord:
    if not member.is_active:
        raise LoanError("利用停止中の会員です")
    if not book.in_stock:
        raise LoanError("この蔵書は貸出中です")
    if len(member.loans) >= LOAN_LIMIT:
        raise LoanError("同時貸出の上限に達しています")

    return LoanRecord(
        member_id=member.id,
        book_id=book.id,
        due_date=date.today() + LOAN_PERIOD,
    )

技法そのものは第6章の早期 return と同じだが、リファクタリングで大事なのは進め方。一番外側の if から1段ずつ反転し、そのたびにテストを回して挙動が変わっていないことを確かめる。一気に書き換えると、どこで壊したか分からなくなる。

参考: 『良いコード/悪いコードで学ぶ設計入門』(ミノ駆動 著、技術評論社)第14章。コード例は原則を自分の題材で表現し直したオリジナル。