名前設計
10-8

真偽値メソッドは is / has / can で

真偽値を返すメソッドは is / has / can などで始め、「クラス名 is 状態」と英文として自然に読める場所に置く。Util クラスの static 判定はデータと判定ロジックが離れるうえ、名前からも True が何を意味するのか読み取れない。

請求書の期日超過チェック

Bad

判定がデータから離れた Util に置かれ、or_not という名前では True がどちらの意味かもわからない

データと判定が離れている
class InvoiceUtil:
    @staticmethod
    def check_invoice_overdue_or_not(invoice: Invoice, today: date) -> bool:
        return invoice.paid_on is None and invoice.due_date < today
Good

「Invoice is overdue.」と英文で読めれば、名前も置き場所も正しい

データを持つクラス自身が is で名乗る
@dataclass(frozen=True)
class Invoice:
    due_date: date
    paid_on: date | None = None

    def is_overdue(self, today: date) -> bool:
        return self.paid_on is None and self.due_date < today

    @property
    def is_paid(self) -> bool:
        return self.paid_on is not None

「クラス名 is 状態」と声に出して読んで違和感がないかが置き場所のテスト。引数なしで判定できるものは @property にすると invoice.is_paid とフィールド感覚で読める。

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

真偽値メソッドは is / has / can で

真偽値を返すメソッドは is / has / can などで始め、「クラス名 is 状態」と英文として自然に読める場所に置く。Util クラスの static 判定はデータと判定ロジックが離れるうえ、名前からも True が何を意味するのか読み取れない。

請求書の期日超過チェック

Bad

判定がデータから離れた Util に置かれ、or_not という名前では True がどちらの意味かもわからない

データと判定が離れている
class InvoiceUtil:
    @staticmethod
    def check_invoice_overdue_or_not(invoice: Invoice, today: date) -> bool:
        return invoice.paid_on is None and invoice.due_date < today
Good

「Invoice is overdue.」と英文で読めれば、名前も置き場所も正しい

データを持つクラス自身が is で名乗る
@dataclass(frozen=True)
class Invoice:
    due_date: date
    paid_on: date | None = None

    def is_overdue(self, today: date) -> bool:
        return self.paid_on is None and self.due_date < today

    @property
    def is_paid(self) -> bool:
        return self.paid_on is not None

「クラス名 is 状態」と声に出して読んで違和感がないかが置き場所のテスト。引数なしで判定できるものは @property にすると invoice.is_paid とフィールド感覚で読める。

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