■ 1. ブール型使用の問題提起
- 基本的な型: ブール型は最初に学ぶ型の一つで、ブール論理が現代のコンピューティングの基盤であるため自然に使用される
- 使いすぎの問題: ブール型を使用するほぼすべてのケースで、別の何かを使用すべき
- 設計改善の効果: 「別の何か」を見つける努力は、システムについて多くを教え、設計を改善する(最終的にブール型を使用することになっても)
■ 2. 日時型(Datetime)への置き換え
- 典型的な使用例: ウェブサイトでメール確認を表すis_confirmedというブール型カラム
- データの損失: ブール型では確認がいつ発生したかという情報を捨てている
- 改善策: ユーザーがメールを確認した日時をnullable列に保存する
- 利点:
- 列がnullかどうかをチェックすることで同じ情報を得られる
- 他の目的のためにより豊富なデータを得られる
- 確認プロセスのバグがあった場合、タイムスタンプを使用して影響を受けるユーザーを特定できる
- 検出方法: ブール値を変更するためにアクションが発生する必要があるか、値が一度だけ変更できるかを尋ねる。両方に該当すれば日時型をブール型に変換していると考えられる
■ 3. 列挙型(Enum)への置き換え
- 残りのブール型データ: 何かのタイプやステータスを示すことが多い
- 典型例:
- ユーザーが管理者かどうかを示すis_adminカラム
- ジョブが失敗したかどうかを示すfailedカラム
- ユーザーがアクションを実行できるかどうかのブール値の返却
- 管理者の例での問題: ブール型を使用すると、最終的にはより多くのカラムが必要になり、他のステータスを追加し続けることになる
- 列挙型による解決:
- UserRole列挙型(User、Admin、Guest、SuperAdmin)を使用
- 新しいケースを簡単に追加できる
- ツールを使用してコード内のすべての新しいケースがカバーされていることを確認できる
■ 4. ジョブステータスの例
- ブール型の問題: is_failed、is_started、is_queuedなど複数のブール型が必要
- 列挙型の利点: 単一のstatusフィールドで様々なステータスを持つ列挙型を使用
- 追加の推奨: 各イベントのタイムスタンプフィールドも必要だが、ステータスも明示的に保存すべき
- 効果: ステータスを保存することで状態機械に似た構造になり、よりクリーンなコードと状態遷移に沿った分析が可能
■ 5. 権限チェックの例
- ブール型返却の問題: trueはユーザーが実行でき、falseは実行できないことを意味するが、型からアプリケーションロジックの意味を推測できない
- 列挙型による改善:
- PermissionCheck列挙型(Allowed、NotPermitted(reason: String))を使用
- 2つの選択肢しかない場合でも列挙型として表現できる
- 追加の利点: 権限チェック失敗の理由を返すなど、より豊富な情報を含められる
■ 6. 列挙型を使用すべき検出方法
- 相互排他的なブール型の増殖: 相互に依存するブール型が増える
- 同時変更: 同時にすべて変更される複数のカラムが見られる
- 長期使用: 長期間にわたって返却され使用されるブール型が見られる
- 重要性: プログラムを保守可能で理解しやすく保つために列挙型を使用することが重要
■ 7. ブール型を使用すべきケース
- 条件式の評価: 条件式の結果を(一時的に)保存して評価する場合
- 最適化の観点:
- コンピュータのための最適化(変数の再利用)
- プログラマーのための最適化(大きな条件式に名前を付けて理解しやすくする)
- 中間値の保存: 中間値を保存することで最適化を図る
■ 8. 条件式での使用例
- 例: calculate_user_data関数でuser_can_do_thisというブール型変数を使用
- 目的: 長い条件式に名前を付けて計算内容を明確にする
- 改善の余地: この場合でも、列挙型のmatchを使用する方が理にかなう場合がある
- 保持の理由: 計算内容に名前を付けるためにブール型を保持する可能性はある
■ 9. ブール型の本質的な問題
- データとロジックの混同: ブール型はロジックには適しているが、データには通常別の何かが隠れている
- 密結合の問題: データとしてブール型を保存することで、そのデータをアプリケーションロジックに密に結合させている
- 根本的な問いかけ: ブール型が依存するデータは何か、代わりにそれを保存すべきではないか
■ 10. 設計原則とまとめ
- 絶対的なルールの不在: すべてのブール型を削除すべきではなく、常に真であるソフトウェア設計の単一ルールはおそらく存在しない
- 批判的思考の重要性: ブール型にもっと注意を払うべき
- 実践による習得: 批判的な姿勢と根本的なデータへの問いかけは実践で容易になる
- 長期的利益: 前もって少し考えることで、長期的には多くの時間を節約できる