その汚いコード、いつどこで整頓するの？"Tidy First?"を読んで解決した話

# Tidy First?
Kent Beckさんの本「[Tidy First? -個人で実践する経験主義的ソフトウェア設計](https://amzn.to/3PFAI9H)」の日本語訳版が出たので読んで色々と感想を交えながら整理してみました。

- 翻訳版が2024/12/25に販売された
- いつどこでコードを改善・整頓すれば良いのかを記述した本
- 3部作の1作目で、本作は"個人"に焦点を当てている

内容整理目的でいくつか気になったポイントを抜粋しつつ、自分で咀嚼し言い換えたり、感想・意見を交えて整理しています。きちん正しく理解するためには本書をぜひ一読することをオススメします。

[**Tidy First? -個人で実践する経験主義的ソフトウェア設計**](https://amzn.to/3PFAI9H)
[<img width = 240 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262161/b9a2790c-1146-0255-c0fe-da4ac676070b.jpeg">](https://amzn.to/3PFAI9H)


※ Kindle版がないのでPDF買うなら[オライリー公式](https://www.oreilly.co.jp/books/9784814400911/)からどうぞ（私は電子書籍派）

## 本書が対象にしている読者

第1部は簡単め（初学者〜）、第2部、第3部はある程度経験がありつつも日々の実務で悩んでいる人向け、という印象。

本書では `プログラマー、リード開発者、現場に出るソフトウェアアーキテクト、技術マネージャー` を対象にしており、 `一般的なプログラミングの経験がそこそこあることを前提とする` と言っているのもあり、初学者が最初に手を取るべき書籍にはならなそう。（※ 初学者で整頓もとい良いコード書きたい人は、本書でも良いとは思うのですが、まずは名著の[リーダブルコード](https://amzn.to/4jkJmrX)とか[プリンシプル オブ プログラミング](https://amzn.to/3E7OD5R)とかを先に読んだほうが良いと思う）

おそらく、「ある程度コードは書けるがコード汚くなりがちだけど何を意識すればいいか迷い始めた人」「チームのコードが汚くて整頓したいけどどうすればいいのか悩んでいる人」あたりに効きそうなイメージです。

本書は、 `プログラミング言語によらず、開発者全員が自分のプロジェクトに本書の概念を当てはめながら読むことができる` とあるので普段の利用言語の制約はないことは嬉しいポイントかと思います。


# 第一部: 整頓

整頓とは小さなリファクタリングとのこと。第一部では整頓術が具体的に書いてある。

## 心に留めておきたい整頓術
初学者ではなければおそらく殆どをなんとなく理解はしているものではある。とはいえ、改めて心に留めておきたいものもあったので下記にPickします。

- ガード節
    - いわゆる早期リターン
    - `ガード節は使いすぎないこと。1つのルーチンに7〜8もガード節があるコードは読みにくい`
- デッドコード
    - さっさと消そうという話
        - *← 激しく同意*
- シンメトリーを揃える
    - 書き方にはそれぞれ良し悪しがあるが、`やり方を1つ選ぼう。他もそのやり方に合わせよう。不要なバリエーションを1つずつ整頓していこう。`
        - *← 統一されていないと読み手が辛い*
- 読む順番
    - `あなたならどのような順番で遭遇したかっただろうか?その順番を次の読み手に贈るのだ。`
        - *← 後続の人への優しさ*
- 説明変数
    - `大きくてややこしい式の一部を理解したら、その部分を意図がわかる変数に抽出する`
- 説明定数
    - `シンボリック定数を作ろう。`（ex. `if response.code = 404` よりも `if response.code = PAGE_NOT_FOUND`）
        - *← 急いでると定数化せずに直書きしがちだけど、あとから頭抱えるやつ*
- ステートメントを小分けにする
    - `空行を入れよう`
        - *← シンプルすぎるけどかなり有効な整理。自分もわりと空行いれて整理するの好き*
- ひとかたまり
    - `小さな部品のやりとりの仕方によっては、コードが理解しにくくなる`
    - `明確さを取り戻すには、まずはコードを1箇所に集めて、それから改めて、簡単に理解できる部品を抽出する`
- 説明コメント
    - `コードを読んでいて「なるほど、それでこうなっているのか」と声が出ることがある。これは貴重な瞬間だ。記録しよう。`
    - `砂に埋めるよりも結合の問題を指摘するコメントを追加しておくほうがはるかにマシ`
        - *← 半年前の自分が書いた謎コードや、暫定対応の処理にコメントが書いてないと困ることがあるが、そういう時こそコメントを追記するように心がけている*
- 冗長なコメントを削除する
    - `# X を返す; return X;` は `コストだけで何もメリットがない`
    - `完全に冗長なコメントは消そう`
        - *← コメント書きすぎの人なので、たまにやってしまうこともありそうなので自戒*

本書では他にも色々な整頓術の紹介があります。

# 第二部: 管理術
個人の開発ワークフローにおいて、「いつ整頓を始めるか？」「いつ整頓をやめるか？」「どのように整頓と、振る舞いの変更を組み合わせるのか？」を説明している。

## いつ整頓をするのか？
以下の4つに分類できる。

- 整頓しない
    - 二度と変更しないコード
- 改めて整頓する
    - すぐに見返りがない
- あとで整頓する
    - 将来の整頓まで待つとかえって高くつく
- 先に整頓する
    - すぐに見返りがある

## どのくらい整頓に時間をかければ良いのか
「大きなリファクタリング」ではなく「数分〜1時間ほどの短い作業」に収めることで、安全かつ効果的に行える

:::note warn
第三章で `結合は1つの整頓、その次、また次と整頓を誘発する。整頓はソフトウェア設計のプリングルスのようなものだ。先に整頓するときは、次を食べたいという衝動を抑えよう。次の振る舞いの変更ができるように整頓する。整頓の暴飲暴食はあとに取っておき、誰かが待っているような変更の遅れがないときに好きなだけ食べよう` と説かれている。全くその通りである（自戒）
:::

## そもそも整頓をPullRequestにどういれるのか

整頓はどこかに入れなければいけないが、PullRequestに盛り込むとレビューが大変になるのはよくある話だとは思う。結論としては、`整頓はそれ用のプルリクエストに入れる。整頓はプルリクエストごとにできるだけ少数にする` ことのよう。

> コードがすばやくレビューされるなら、小さなプルリクエストをたくさん作る力が働く。焦点を絞ったプルリクエストであれば、レビューも速くなる。この強化ループは逆方向にも同じように作用する。遅いレビューが大きなプルリクエストを促し、そのあとのレビューがさらに遅れる。

> 整頓のプルリクエストではレビューを必須にしない実験をしてみよう。こうすればレイテンシーは減り、さらに小さい整頓のプルリクエストを作るインセンティブになる

このあたりは、分かりみはありつつ、PullRequestのレビューが必須な設定になっているプロジェクトではどうするものかな…というのもありそう。例えば、整頓PullRequestについては

- Botが承認する
- 普段のレビュアーの枠を超えてエンジニアにアサインされて誰かがサクッと見て承認する。例えばレビューにかける時間は基本1〜3分以内とかそういう軽い認識にするとか。

のような仕組みで対応できるのかもしれない。（求む：他のやり方）

:::note info
（追記）いつもお世話になっているエンジニアの方々と雑談する機会があったので、このお話をしてみたところ、

- Linter（ex. eslint）を導入している
- 静的型付け言語（ex. TypeScript）でミスに気がつける
- テスト（unit〜e2e）がある程度書かれている

という場合なら、整頓で間違えてやらかすというヒューマンエラーなリスクもある程度少ないと言えるしBot承認でもいいかもねというお話が出た。

あとは、整頓タグつけたPRは、最近流行りの感じでAIがレビューしてApprove判定するとかもアリかもしれない。まずはこういう所から導入するのも丁度よいかも。
:::

> チームに信頼があり盤石な文化があれば、整頓にはレビューは不要だ。整頓はレビューしなくてもよいというレベルの安全と信頼に到達するには、何か月もかかる。練習しよう。実験しよう。みんなでエラーをレビューしよう。

とのこと。やってみるしかない。


# 第三部: 理論
## なぜ整頓をするのか？
「なぜ整頓するのか？」という話。ここが結構難しい（理解がズレていたらすみません）。

ざっくり言うと将来へのオプショナリティへどう向き合うかという話（[金融のオプション取引](https://www.rakuten-card.co.jp/minna-money/securities/stock/article_2111_00006/#h_48133)が例）を軸に整頓について考えられている。

オプショナリティとは「将来の変更や選択肢を柔軟に行使できる状態が、あらかじめ内在していることによって生まれる価値」であり、本書では`価値予測の不確実性が高いほどオプションの価値は高くなる`と言っている。


## 先に整頓をするか？

- `cost(整頓) + cost(整頓のあとに振る舞いを変更) < cost(整頓せずに振る舞いを変更)`
    - 間違いなく「先に整頓」して良いと判断できる
- `cost(整頓) + cost(整頓のあとに振る舞いを変更) > cost(整頓せずに振る舞いを変更)`
    - いわゆる判断が難しい部分。ここをオプショナリティとの兼ね合いで判断する

ここで、オプション価値を高める整頓とは何かという疑問が出てくるかとおもう。基本的には

- コスト：小さくなるか・発生が遅くなるか・発生確率が低くなるか
- 収益：大きくなるか・発生が早くなるか・発生確率が高くなるか
- 結合：少なくなるか
- 凝集：高くなるか

あたりを踏まえ判断するのがよさそう。

:::note warn
・結合が強いと、ある要素を変更するときに別要素も変更しなければならず、"新しい変更をしようとすると大掛かりになってしまう" = "オプションを行使しにくい状態"を生む。

・凝集を高めて「関連する要素は近くにまとめる」ことで、将来の変更対象が局所化し、"変更コストが小さい" = "選択肢を増やしやすい状態"を作れる。

本書では `整頓によって凝集度を高めれば、振る舞いの変更が簡単になる。凝集度を高めれば、分離の妨げとなっているものを取り除くこともできる。凝集度を高めることで、結合があっても平気でいられるようにもなる` とも言っているので、まずは凝集を高くするのを考えてみても良いのかもしれない（？）
:::

# まとめ
色々整理して書いてたら結構時間を使ってしまった。第三章は特に難しいので何度か読んでも良いかもしれない。

## 本書のまとめ
自分の理解としては以下のあたりかと考えている。

- 「コスト・収益・結合・凝集」の観点から、整頓のタイミング・可否を判断する
- 整頓では将来の機能追加・仕様変更など不確実なニーズに柔軟に対応できるようなコード構造を作ることで、「あとからやる/やらない」を自由に選べる選択肢(オプション)を増やす

## 本書を読んだ感想

本書が言っていることは、数年働いたエンジニアであれば何となく無意識で理解している内容だと思う。ただ**適切に言語化されている**ので、「ここの整頓をしたい！」「整頓したほうが良いのでは？」という話になったときに **"なぜ整頓をするのか"をきちんと説明できるようになる** かと考えている。

この本は、エンジニアの同僚が全員が読んで、整頓に対する知識を均し、それを踏まえたチームへの信頼が高まって最大効力を発揮しそうな気がする。特に上にも書いたが整頓のPullRequest周りをどうするべきかは各PJの文化などもあると思うので尚更である。

本書を通じて色々なことを考えるキッカケになる一冊になると思いました。1作目の本書は個人を軸に進みましたが、2作目「Tidy Together?」はチームを扱うとのことなので、次回作も楽しみにしております。