Interactive

プログラミング

このセクションでは、言語やフレームワークをまたいで使う実装上の判断基準を扱います。文法やAPIの使い方は、対象バージョンの公式ドキュメントを参照します。

基本方針

  • 読み手が処理と失敗条件を追える、明示的なコードを選ぶ
  • 計算や判定は純粋な処理に寄せ、I/Oや時刻などの副作用を境界へ集める
  • 将来の可能性ではなく、現在ある変更理由に合わせて抽象化する
  • 型と実行時検証は、不確かな値が入る境界で使う
  • フォーマットと静的解析の結果は、個人の好みより優先する

行数、引数の数、ファイル数だけで設計の良し悪しを決めません。責務が一つで、名前と入出力から意図を理解でき、変更理由がまとまっていることを重視します。

概要

値の表現を決めるときは、まず値がどの境界から来て、実行時検証が必要かを確認します。状態によって必要な値が変わる場合や、同じプリミティブ型を安全に区別する必要がある場合の選択は型システムで扱います。

計算や変換は関数から始め、状態、依存関係、プロジェクトで統一したユースケースの境界を保持する必要がある場合にクラスを選びます。詳しい条件は関数とクラスにまとめます。処理の失敗は、呼び出し元が分岐する想定内の失敗か、共通の境界まで伝える想定外の失敗かをエラー処理で区別します。

処理の分割と共通化は、行数や見た目の重複ではなく、独立した名前、テスト、変更理由を持つかで判断します。

名前と配置

名前は役割や業務上の意味を表します。dataresultのような一般名も、短い局所スコープで意味が一意なら問題ありません。広いスコープや複数の値が並ぶ場所では、residentChargessaveResultのように区別します。

ファイルの分割は、1ファイルに1つの関数またはクラスを基本にします(モジュール設計)。密接に関連する小さな型や定数は同じファイルに置いてよく、公開APIを増やす分割は、利用側の見通しが本当に良くなる場合に限ります。

抽象化

重複が似て見えるだけでは共通化しません。入力、出力、例外、変更理由が同じと確認できたときにまとめます。薄いラッパー、利用箇所が一つだけの汎用ヘルパー、実装を一つしか持たない先回りのインターフェースは避けます。

まず対象のユースケースを直接読める形で完成させます。複数の実例から安定した境界が分かった後で、関数、型、モジュールへ抽出します。