はじめに
『Tidy FIrst?―個人で実践する経験主義的ソフトウェア設計』をGoogleのAIノートツールであるNotebookLMを利用して読んだ。
この本は、各所で紹介されており気にはなっていたものの、他に学習すべきことが多く、後回しになってしまっていた。今回NotebookLMを使って効率よくインプットすることに挑戦してみた。オライリー本はpdfで電子書籍を買うことができるので、NotebookLMに読み込ませることができる。今後はオライリー本はkindleではなく、pdfで買おうと思う。
読んだステップ
まずは音声概要を生成
10分ほどの2人で話しているPodcast風の音声が生成される。何かしながらでも聞けるし、どういう本なのかをざっくり掴んで読みたい気持ちを高めることができた。

「はじめに」と「目次」を読んだ
ここは全体を表すところなので、書籍の本体を読んだ。
特に以下2つのパートは、目的意識を持って読み進めるのによかった。
学べること
本書を読み終えるころには以下のことが理解できているだろう。
私の目標は、読者が午前中に本書を読み始めたら、午後には設計が上達して
いることだ。
全体の要約を読んだ
「5分で読める程度で要約してください」とお願いして、生成してもらった要約を読んだ。「レポート」という機能もあったので、そちらを読んでもよかったかもしれないと後で思った。
ここで、Tidy とは「整頓」であるとのことがわかった。小さく始めよう、という意味かと思っていた(Tinyと勘違いしていた)が、「先に整頓すべき?」という意味だった。
第一部をリスト化してもらい、想像ができないところだけ読んだ
この本は三部構成なので、ここからは部ごとに読み進めることにした。
第一部では、整頓の技術を章ごとに紹介されているので、説明や実例とともにリスト化してもらった。想像できるところ(例えば「ガード節」は聞いたことがあり想像できる)は、リストの内容を読み、想像できないところは書籍本体を読んだ。
こんな感じで出力された。
| 章 | 整頓の技術 | 説明と実例の要点 | 引用元 |
|---|---|---|---|
| 1章 | ガード節 | ネストした条件式を避け、ルーチンの冒頭で事前条件を明確にしてすぐにリターンするようにコードを整頓します。これにより、コードの細部に立ち入る前に、必要な事前条件が明白になり、分析しやすくなります。 | 『整頓の技術』第1章 |
書籍本体を読んでもピンと来なかった部分は、「6章の凝集の順番で、「分離」と言っているのはどういう意味でしょうか?」などと質問して理解を深めた。6章以降の文脈も踏まえて答えてくれたので、これはAI利用読書ならではだなと思った。
第二部の要約を読んだ
「第二部を仕事に活かしたいです。仕事に活かせるように要約してください」と依頼して要約してもらった。このプロンプトが良かったかはわからないが、わかりやすく要約してもらえた。
第二部は「管理術」で、主にいつどれくらい「整頓」をすべきかという話だった。
第三部の要約を読んだ
同じように第三部も要約してもらい読んだ。要約でよくわからない部分や気になる部分は書籍本体に戻って読んだ。第三部は本体を読んだ割合も結構多かった。それでもよくわからなかった部分は、実例も出してもらった。本文に書いていない具体例も出してくれるのはとても助かる。
↓よくわからなかった部分の具体例を出してもらった。
あなたは、システム全体で顧客 ID を表すのに 32ビット整数(integer)を使用していますが、顧客数が急増し、64ビット整数(long)に変更する必要があると判断しました。この変更は、コードベースの100万箇所に及ぶ可能性があり、不可逆的な大がかりな作業です。
戦略:小さな整頓のスライスで進める
この巨大な変更を、「1回に 1つの整頓」に分割して対応します。
ステップ 1: 新しい型を導入する(先に整頓する)
まず、すべての場所を一度に変更するのではなく、新しい型(CustomerIdLongなど)を導入し、古い型を透過的にラップする小さな整頓を行います(「新しいインターフェイス、古い実装」の考え方にも近い)。
• 整頓内容: 顧客 ID を扱うすべての関数で、新しい long 型を返す新しいインターフェイスを定義し、古い integer の呼び出しをラップします。
• タイミング: 先に整頓する。これにより、新しい型への移行という振る舞いの変更(新しい顧客 ID の利用開始)を、より安全かつ安価に進めるオプションが生まれます。
ステップ 2: 振る舞いを変更する(新しい型の利用開始)
新しい型のラッパーができたので、新しい顧客 ID を生成し、システムの一部で利用を開始します。この振る舞いの変更は、まだ限定的な範囲で行われます。
ステップ 3: 結合を解きほぐす整頓を続ける(改めて整頓する)
新しい型への移行は時間がかかります。すべての呼び出し元を一度に変更するとチームに大きな負担がかかるため、日々の開発の合間に、影響範囲を限定した小さな整頓を続けます。
• 整頓内容: 古い integer 型に依存しているコードブロックを見つけ、それを新しい long 型を明示的に使用するように変更し、古い型のコード(デッドコード)を削除します。このとき、変更が連鎖しないように、1回に 1つの依存関係だけを処理します。
復習
レポートを生成し、読んで思い出せなかった部分を質問したりしながら理解を深めた。
練習問題
いくつかの「整頓の技術」について、コードを書いて実践してみた。NotebookLMに練習問題を出してもらい、コードを修正した。
以下のプロンプトで聞いてみたところ、
第一部の整頓の技術について、いくつか実践してみたいです。
あなたがコードを提示して、私がそれを修正するエクササイズ形式でお願いします。言語はphpでお願いします
問題が出てきた。
エクササイズ 1:ガード節
「ガード節」(Guard Clauses)の目的は、ネストした条件で読み手が迷子になりがちな状況を改善することです。コードの細部に立ち入る前に、念頭に置くべき事前条件を最初にチェックし、条件を満たさない場合はすぐに処理を抜ける(returnするなど)ように整頓します。
以下に、ネストした if 構造を持つPHP関数を提示します。これを「ガード節」を使って整頓してみてください。
元のコード(PHP)
この関数は、ユーザーデータと購入金額に基づき、割引額を計算します。
<?php
function calculate_discount($user_data, $amount) {
// 1. データが有効かつ会員であるかチェック
if (isset($user_data) && $user_data['is_member']) {
// 2. 金額が最低要件(100より大)を満たしているかチェック
if ($amount > 100) {
// 3. 割引率を計算
$discount_rate = 0.10;
// 4. VIPステータスをチェックして割引率を上げる
if (isset($user_data['vip_status']) && $user_data['vip_status']) {
$discount_rate = 0.20;
}
// 5. 割引額を返す
return $amount * $discount_rate;
} else {
// 要件未満
return 0.0;
}
} else {
// 非会員またはデータなし
return 0.0;
}
}
修正の指示
この calculate_discount 関数を、ソースで推奨されている「ガード節」の技術を用いて整頓し、ネストを解消してください。
整頓後も同じように条件を正しく満たせる場合だけ、ガード節に整頓することが重要です。ガード節は、「if (not 条件) return」の形をとり、事前条件を明白にすることでコードを分析しやすくします。
どうぞ、修正後のPHPコードを提示してください。
これはとても助かる!!これで何回か実践したらだいぶ頭に入りそう!修正したものをチェックして評価してもらえるのもとてもありがたい!!
他の章も同様に問題を出してもらった。最終的には実際のコードを直してみるのがよいのだろうが、典型的な例で型を覚えられるのはとても効果がありそうだ。また、うまく直せなかった部分のお手本回答をもらうことができるのもよかった。今後この使い方はもっとやっていきたい。
今回は実際にコードを書くほうがよさそうだったので問題を出してもらったが、デフォルトで「フラッシュカード」「テスト」機能もあるので、書籍の内容によってはそちらを使ってもよさそう。
良かった点・微妙だった点
良かった
- 練習問題を出してもらい、回答を評価してもらったり、お手本回答を出してもらえるのは良すぎる。コーディングや設計系の書籍でこれをやって型を覚えられたらとてもよさそう。
- 第一部のリスト化は理解しやすく、とてもよかった。特に今回は若干本文が抽象的なところもあったので、本文を読んだ章も、先にリストの説明を見ておくことで理解しやすかった。
- 本文中の単語の意味がわからないとき、質問すると、書籍全体を読んだ上での意味を回答してくれて理解が進んだ。
- 結局どういうことだったか?となった時に気軽に聞いて復習できた。
微妙だった
- 全文読んでいるわけではないので、細かいニュアンスなどは落ちているかもしれない。ただ、一言一句読んだからと言って頭に入るわけではないので、要約と本文を行き来するほうが頭に入っているようには思う。本文をしっかり読みたい度合いによって本文に戻る割合を変えてもいいかもしれない。
- オライリーはpdfを配布してくれるから良いが、kindleだと読み込めない。(裏技を使って無理やりpdfにすれば読み込めるようだが...。)
Tidy First? で印象に残ったこと
先に整頓すべき時と後で整頓すべき時がある
先に整頓すべきか、あとにすべきかという問いの答えは「状況による」とのこと。設計はよくするのが正義と思っていたので、いつでも整頓すべきというわけではないというのは意外だった。 "cost(整頓) + cost(整頓のあとに振る舞いを変更) < cost(整頓せずに振る舞いを変更) が成り立つ" 場合は、先に整頓するのが良いとのこと。
| パターン | タイミングの条件 | 仕事で得られる主な価値 |
|---|---|---|
| 先に整頓する | すぐに見返りがあるとき。例えば、コードを読んで理解している段階で、整頓によって理解が向上するとき。あるいは、整頓することで振る舞いの変更を安く行えることが明らかなとき。 | 変更のコストを下げ、オプションを生み出す。 |
| あとに整頓する | 振る舞いの変更の最中に整頓の機会を見つけたが、すぐに分離するとコストが高くなるとき。将来すぐに同じ領域の振る舞いを再び変更するつもりがあるとき。 | 変更のたびにコードを良くする(ボーイスカウトルール)。整頓コストが変更コストに比例するときに合理的。 |
| 改めて整頓する | すぐに振る舞いの変更に結びつかないが、最終的には見返りがある大きな整頓を抱えているとき。 | 散らかっていることによる「税金」を減らす。学習ツールとして構造を理解し、気分が良くなる(セルフケア)。これを「お楽しみリスト」として扱い、時間があるとき(数分~1時間)に取り組む。 |
| 整頓しない | そのコードを二度と変更しないことが確実なとき。 | 無駄な労力を避ける。 |
整頓は可逆的なもので、不可逆のものと完全に同じプロセスだと無駄がある
整頓(構造の変更)はヘルパー関数の抽出のように、気に入らなければ簡単に元に戻せる。 一方、振る舞いの変更(機能のデプロイ)は不可逆的であり、大きなデメリットを避けるために慎重なレビューが必要。 可逆的な整頓と不可逆的な変更に、レビューなどの同じ投資をするのは無駄なので、整頓は低リスクとして扱うべきとのこと。この考え方はしたことがなかったが、確かにそうだ。
細かい単位で整頓していく
大きな設計変更が必要な場合でも、小さなステップ(中断可能なスライス)で進めることで、間違いに気づいても簡単に元に戻せる。
整頓しつづければいいというものではない
本書では整頓を「整頓はポテトチップスのようなものだ。1 つ食べれば、もう1 つ食べたくなる。整頓をしたい衝動を抑えることが、整頓スキルのカギとなる。整頓し終わった。もっと整頓すべきか?それは時と場合による。」と書いている。
整頓すればするほど良い、というわけではないことは意外だった。たしかに、本書にあるような本当に小さな整頓なら、機能追加の合間にできるかもしれない。
結合(を減らす整頓)の基準
「整頓によってより少ない要素の変更になるか?」を基準に整頓する。一箇所結合を無くしたら他の結合が増えるトレードオフが生じるとのこと。クラス設計の基準がよくわからなかったので、このシンプルな基準は取り入れやすそう。
凝集の基準
「整頓によって変更が必要な要素が、より小さく、もっと集中した範囲になるか?」を基準に整頓する。結合と同様にシンプルな基準で取り入れやすそう。
おわり
NotebookLMを使うことで、短時間で書籍の内容をインプットでき、実践の練習もすることができた。NotebookLMがなければきっとこの本はもっと後回しになっていただろう。一方で、なんとなく全部の原文を読んでいない、という後ろめたさもある。しかし全文読んだからといって頭に入るわけではない。内容的にはむしろ全文読んだよりも頭に入っている割合は多そうに思う。この後ろめたさには慣れていく必要がありそうだ。
参考URL
https://note.com/leoo/n/n6b877448d51a
https://zenn.dev/maya_honey/articles/a64c5a06aea420
https://note.com/google_gemini/n/n75516598b159#789efa28-ec37-490d-ae61-735dad3c2322
