書籍「リファクタリング」から僕が履修漏れしてた部分を伝えたい

## エンジニアの必読書を読んでいない・・・！！

[「Learn things that don't change」](https://newsletter.techworld-with-milan.com/p/learn-things-that-dont-change?ref=dailydev)という海外の記事で、「2024年の全エンジニアが読まなければならない本」(下の画像)が紹介されており、その中でマーチンファウラー著「リファクタリング」を読んでいないことに気づきました。  
(中段左のGoodPracticesのRefactoring)

![books](https://substackcdn.com/image/fetch/w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcba05c59-8949-4114-a17d-3f7f8d482a67_7176x4464.png)

引用: [「Learn things that don't change」](https://newsletter.techworld-with-milan.com/p/learn-things-that-dont-change?ref=dailydev) 

新卒でエンジニアリングを本格的に始め、早30歳を過ぎた私ですが、ソフトウェアエンジニアの必修科目を履修するため「リファクタリング」今更読みました。

この「リファクタリング」という本を読んでいて、
内容としては、「まあそうだよね〜」というのも多いのですが、その中でも本を読むまで言語化しきれてなかったところがあったので、それを書き連ねていきます。

## 忙しい人のために

- リファクタリングの目的とは？
  - 経済的なメリットがあるからやるものである
- リファクタリングをすべきでないタイミングとは
  - 機能追加をしている時
  - 作り直した表が早い時
  - 今動いていて、中身を変更しないものである時
- リファクタリングをすべきタイミング
  - コードを理解しようとする時
  - 新しい機能を追加する直前
  - 開発にてコードを触った時
  - 三度目に同じコードを見た時
- リファクタリング力をつけるためにボキャブラリーを増やそう
  - [書籍「リファクタリング」](https://amzn.asia/d/07lDH5b7)
  - [refactoring-guru](https://refactoring.guru/ja/refactoring)

## リファクタリングとは

本書では名詞としてのリファクタリングと動詞としてのリファクタリングが紹介されてたので、それぞれ引用します。

``` text1
リファクタリング （名詞）外部から見たときの振る舞いを保ちつつ、 理解や修正が簡単になるように、 ソフトウェアの内部構造を変化させること。 
ＭａｒｔｉｎＦｏｗｌｅｒ. リファクタリング 既存のコードを安全に改善する（第2版） (p.45). Kindle 版. 
```

``` text
リファクタリングする （動詞）一連のリファクタリングを適用して、 外部から見た振る舞いの変更なしに、ソフトウェアを再構築すること。
ＭａｒｔｉｎＦｏｗｌｅｒ. リファクタリング 既存のコードを安全に改善する（第2版） (p.45). Kindle 版. 
```

名詞の方の「リファクタリング」の意味である、外から見た振る舞いはそのままで良い感じに修正する、というのがリファクタリングです。

この「リファクタリング」を複数重ねて実施することが、「リファクタリングする」という行為であると理解しました。

## リファクタリングの目的の本質

ここが少し勘違いしていたポイントのひとつでした。

これが理解できると、よく聞く「企画サイドの人間にリファクタリングの重要性を理解してもらえない」みたいなところに刺せるかなと思います。

リファクタリングの目的の本質は、 **「経済的なメリットを出す」** ということです。

リファクタリングをすることで、

- コードが読みやすくなる
  - 新機能の追加がしやすくなる
  - トラブル発生時に問題箇所がわかりやすくなる

というのがよく言われますが、「コードが読みやすくなる」は目的ではありません。コードを読みやすくするのは、経済的なメリットがあるからです。

コードが読みやすくなると・・・

- 新機能の追加がしやすくなる  
→ 機能追加時にコード理解が速くなったり、変更しやすいコードになっている  
→ 工数削減になる  
→ 人件費が下がって **経済的なメリットがある**
- トラブル発生時に問題箇所がわかりやすくなる  
→ 障害時にコード理解が速くなったり、変更しやすいコードになっている  
→ 工数削減になる  
→ 人件費が下がって **経済的なメリットがある**

上記のようにリファクタリングの目的の本質は、 **「経済的なメリットを出す」** です。そのため、経済的なメリットがでないリファクタリングはする必要がないはずで、経済的なメリットを出すためにリファクタリングは実施されるべきです。

## リファクタリングをすべきでないタイミングとは

経済的なメリットがないリファクタリングはするべきではありません。

リファクタリングをすべきでないタイミングは、

- 機能追加をしている最中
- 今動いていて、中身を修正する必要がない
- 作り直した方が早い時

です。それぞれブレイクダウンして書いてみます。

### 機能追加をしている時

ちょっと極端な言い方ですが、機能追加をしながらリファクタリングをしてはいけません。機能追加のコーディングが始まる前or終わった後にリファクタリングをしましょう。

「リファクタリング」の書籍の中では、「二つの帽子」という言い方で説明されてます。

- 二つの帽子とは、開発する時に「コーディングの帽子」と「リファクタリングの帽子」の二つの帽子をそれぞれかぶって仕事をするという考え方
  - コーディング(開発作業)をしながらリファクタリングをするべきではない
  - コーディングがひと段落したらリファクタリングをすべき

上記の考え方は[テスト駆動開発(TDD)のRed→Green→Refactorの流れで開発をする](https://medium.com/@fideraphael/tdd-d1b5e1205b51)、というのに似ているなと感じました。

開発中はひとまず動くコードを書き、ユニットテストで動作を保証した状態でリファクタリングをするべきである。というのは、「リファクタリング」でも書かれています。
ユニットテストがないと既存のコードの振る舞いが壊れていないかを効率よく確認することはできません。コーディングにより動くコードとユニットテストを手に入れたのちにリファクタリングをすることで、経済的にメリットのある形でコーディングとリファクタリングができるようになるでしょう。

### 今動いていて、中身を修正する必要がない

コードの中には今とりあえず動いているけど、ちょっと中身がいけてないんだよなあ、、、というのもあると思います。

しかし、それに対するリファクタリングはグッと堪えましょう。なぜなら、そのコードはすでに動いているし、機能追加等も予定されていないため、リファクタリングをしたとしても経済的メリットが出せません。

しばらく後になって、そのコードに対して修正タスクが発生した際に、リファクタリングをするようにしましょう。

### 作り直した方が早い時

「ええい！このコードは修正するよりも最初から書き直した方が早い！！」

こんな時はリファクタリングではなく、黙って作り直しましょう。とのことでした。

ただ、この判断については明確な基準はなく、そのコードを触るエンジニアのプロとしての嗅覚によって判断されるものになると思います。

## いつ、どのタイミングでリファクタリングをすべきか？

こちらも面白いポイントで、実践できてないものがありました。

リファクタリングをすべきタイミングは

- コードを理解しようとするとき
- 新しい機能を追加する前
- 醜いコードを見かけたとき
- 三度目に同じコードを見かけたとき

一つ目と二つ目については、私は実践しておらず、ハッとさせられました。

それぞれブレイクダウンしていきます。

### コードを理解しようとするとき

新しいプロジェクトに入った際や今まで触っていなかった部分のタスクを実施する際に、コードを読むことがあると思います。それは、コードが何をおこなっているのかを理解するためです。

本書ではそんなときに、リファクタリングしてみてはどうか？という話をしています。

知らないコードを読んでいてそれがぱっと何をしているのか理解できない場合、一目でわかるようにリファクタリングできないかを考えてみます。そして、実際にリファクタリングをし、テストが動くのであれば、「頭の中の理解は正しい」ということになります。

リファクタリングされたコードはより良いコードになっているはずで、それは自分のためにもチームのためにもなる。リファクタリングされたコードは自分の理解を深め、設計上考慮すべき新たな情報を得られるかもしれません。これは、リファクタリングをせねば気づけなかったことです。

### 新しい機能を追加する前

既存のコードが悪くて機能追加が大変？　だったら、既存のコードを直してから機能追加したら良いじゃない。という考えです。

この記事をここまで読んでいただいたあなたには釈迦に説法ですが、きちんと構造化されたコードは、構造化されてないコードに対して、機能追加が楽です。そのため、構造化をしてから機能追加をしましょう。

TDDは機能追加のコードを書いた後にリファクタリングをする考えですが、機能追加のコードを書く前にリファクタリングしても良いのです。

これもいままで私が実践してなかった考え方で勉強になりました。

### 醜いコードを見かけたとき

これはいわゆる[ボーイスカウトルール](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E3%83%9C%E3%83%BC%E3%82%A4%E3%82%B9%E3%82%AB%E3%82%A6%E3%83%88-%E3%83%AB%E3%83%BC%E3%83%AB/)です。

開発を実施した箇所やその付近で醜いコードを見つけたら、ゴミを拾うように醜いコードを取り除いてあげましょう。

### 三度目に同じコードを見かけたとき

こちらは[DRY原則](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/DRY%E5%8E%9F%E5%89%87/)です。
同じコードを見かけたら共通化しましょう。  
この、「同じコードを見かけたら」という部分には流派があり、「二度目に見たらまとめよう派」と「三度目に見たらまとめよう派」があります。

DRY原則はDon't Repeat Yourselfの略なので、文字通り解釈すると「二度目に同じコードをみたら、リファクタリングしてまとめよう」という考えだと解釈してます。  
本書では「3ストライクでリファクタリングする」考え方のようです。

個人的にも3回派です。

## リファクタリングの力を向上するために

「リファクタリング」という書籍を読んでいて、リファクタリングの力を向上させるためにはやはり、醜いコードを認識し、それに対する解決策を持っているか？ということだと理解しました。

それは、結局情報のインプットと実践を繰り返していくしかないなと思います。

「リファクタリング」では、全11章中7章がリファクタリングのパターンのカタログになっています。そのため、リファクタリングのボキャブラリーを増やしたい方はぜひ購入してみてください。辞書的に見ることが多いと思うので、個人的には紙がおすすめです。(電子で買ってしまった・・・)

また、英語サイトですが、[REFACTORING-GURU](https://refactoring.guru/ja/refactoring/smells)というサイトも良いのでおすすめです！

## まとめ

書籍「リファクタリング」を読んで学んだことのなかで、自分が履修できてなかった部分を含めてアウトプットしてみました。
まとめると、

- リファクタリングの目的とは？
  - 経済的なメリットがあるからやるものである
- リファクタリングをすべきでないタイミングとは
  - 機能追加をしている時
  - 作り直した表が早い時
  - 今動いていて、中身を変更しないものである時
- リファクタリングをすべきタイミング
  - コードを理解しようとする時
  - 新しい機能を追加する直前
  - 開発にてコードを触った時
  - 三度目に同じコードを見た時
- リファクタリング力をつけるためにボキャブラリーを増やそう
  - [書籍「リファクタリング」](https://amzn.asia/d/07lDH5b7)
  - [refactoring-guru](https://refactoring.guru/ja/refactoring)

です。

エンジニア必修の書籍の中でもまだまだ履修できてない書籍があるので、着実に履修していきたいです。  
また、こちらの記事はPodcastの原稿として作成しました。さらに細かい話をPodcastでもしてるので、ぜひ聴いてみてください！

↓↓↓

https://open.spotify.com/episode/4wCIHwrIPjiL9w3XKdb0uG?si=qmGhbLkcToqLpe8TolUCkA