「Tidy First?」の読書メモ。あとで見返す用に、印象に残ったところと自分の感想を雑に残しておく。
読後に理解できているはずの観点(まえがきより)
- 振る舞いの変更と、構造の変更の基本的な違い
- 1人のプログラマーが、構造への投資と振る舞いへの投資を交互に行うための考え方
- ソフトウェア設計がなぜ機能するのかの基本理論と、設計に影響を与えるフォース
- 先に整理することで、自身のプログラミング体験を改善できること
- 大きな変更を、小さく安全な手順で始めること
- いろんな動機を持った人が関わる活動だと意識して設計に備えること
経験主義的ソフトウェア設計
ソフトウェア設計では「何」を設計するかがよく議論される。
- サービスの大きさはどのくらいが良いか
- リポジトリの大きさはどのくらいが良いか
- イベント VS 明示的なサービス呼び出し
- オブジェクト VS 関数 VS 命令形コード
第1部 整頓
手法のカタログ。メモしておきたいもの。
- ガード節
- コードの細部に入る前に、念頭におくべき事前条件がある
- デッドコード
- 消そう。実行されないコードは消すだけ
- (感想)AIが部分的に見て処理を書いた結果、実行されないコードがいくつも生成されていることがある。一度AIに書かせたあと、再度AIか人間のチェックを入れよう
- 書き方を揃える
- 同じ問題でも、取り組む時期や人が違えば別の形で解決されることがある
- 透過的なインターフェースを作るのは、ソフトウェア設計における最小単位の本質。振る舞いをちょっと変えたいときに変更が簡単になる
- テストファーストでコーディングする。成功しなければならないテストから始める
- 凝集の順番
- 振る舞いを変えるために、コード中にばら撒かれた箇所へ変更を加えないといけないと気づくことがある
- コードの順番を入れ替えて、変更対象の要素が隣接するようにしよう
- 変数の宣言・初期化を先頭に持ってこよう
- 説明変数
- 式は成長する。小さく始めても成長し続ける
- 式に説明をつけて小さく理解できるようにする。苦労して勝ち取った理解をコードに落とそう
- 説明定数
- マジックナンバーはやめよう
- ステートメントを小分けにする
- ヘルパーを抽出する
- 他のコードとの相互作用が限られているコードブロックをヘルパールーチンとして抽出しよう
- 小さな部品に分けすぎるとコードが理解しにくくなる。探すべき予兆:
- 長くて繰り返しの引数リスト
- 繰り返しのコード、条件式
- ヘルパールーチンの良くない名前付け
- 共有の可変データ構造
- 説明コメント
- コードからは読み取れないことを説明コメントで書く
- 冗長なコメントを削除する
- 「xを返す」→
return x。メリットがない。読み手の時間を無駄にしただけ
- 「xを返す」→
(感想)AIのSKILLにこの観点を入れるのもいいかもしれない。
第2部 管理術
いつ整頓を始めるか / いつ止めるか / 構造の変更と振る舞いの変更をどう組み合わせるか → 状況による。
- プルリクエストをまとめたり分けたりするのはトレードオフ
- 巨大なPRは全体像はわかりやすいが、レビュアーが役に立つフィードバックを返すには大きすぎる
- 小さいPRは細かいフィードバックを促すが、枝葉末節にとらわれるリスクもある
- あまりにたくさん・早く変更しすぎないよう注意。一つの整頓の失敗は、整頓の連鎖の成功よりもコストが高い
デプロイ前に検討すべきこと2つ
- どれだけ整頓すべきか。次の振る舞いの変更をサポートするのに、どれだけ構造的な変更が必要か。整頓ははるか先の未来ではなく、当面のニーズに対応するもの
- どれだけの整頓なら、統合してデプロイするのが簡単になるか
→ レビューのコストを減らし、バッチサイズを小さくすることで整頓のコストを減らす。
先に整頓 / あとで整頓 / 整頓しない
- 本当に静的なシステムなら「壊れていないなら、直さなくていい」が合理的
- 後回しにしても整頓はできる
- 改めて整頓する = 十分な時間があるなら何をするか、を後から拾いにいく
- 改めて整頓することは、散らかっていることの税金を減らす
先にやるか判断するための質問:
- この散らかった箇所を変更するのはどのくらい大変か。整頓しても変更が楽にならないなら、先に整頓しない
- 整頓の利点をどのくらいすぐ得られるか。まだ読んで理解している段階でも、整頓すれば理解が早まる。ならば先に整頓しよう
- この整頓はどう償却されるか。一度しか変更しないなら整頓は控えめに。何年も毎週見返りがあるなら整頓しよう
- 整頓にどのくらい自信があるか。憶測に流されない。「ここが散らかっている。これが無くなれば変更は簡単になる」
まとめ(4象限)
- 整頓しない: 二度と変更しない / 設計から学ぶことがない
- 改めて整頓する: すぐ見返りのない大きな塊がある / 完了すれば最終的に見返りがある / 小出しにできる
- あとで整頓する: 将来まで待つとかえって高くつく / やり切った感が得られない
- 先に整頓する: すぐ見返りがある(理解が向上する、振る舞いを変えやすくなる) / 何をどう整頓すればいいか分かっている
構造と振る舞い
しっかりした構造は部分からできている。
- 細胞小器官 → 臓器 → 生物
- 原子 → 分子 → 結晶
- ソフトウェア: トークン → 式 → ステートメント → 関数 → オブジェクト/モジュール → システム
「システムの構造」とは:
- 要素の階層
- 要素間の関係性
- その関係性から生まれる利益
これで構造と振る舞いをより明確に区別できる。
心に残った言葉
- 料理をしながらでもキッチンは美しく保てる
- ソフトウェア設計は振る舞いの変更への準備。今日の設計は、明日の振る舞いの変更を「購入」できる「オプション」に対するプレミアム
- 設計判断のほとんどは簡単に戻せる。間違いを避けることにはほとんど価値がないので、そのために多く投資すべきではない
- コストのかかるプログラムは、1つの要素を変えるために他の要素も変えないといけない。コストのかからないプログラムは局所的な変更で済む
- ソフトウェアのコストを下げるには結合を減らす。ただし分離もタダではなく、トレードオフの関係にある