[図解][解説動画付き] リファクタリングの原則

<iframe width="560" height="315" src="https://www.youtube.com/embed/vKMh94C43FE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# はじめに
- この記事はリファクタリング本の第2章「リファクタリングの原則」の図解まとめです
    - 【書籍概要】「[Refactoring: Improving the Design of Existing Code](https://t.co/7fRv2P4CAK)」
        - [アジャイル17人衆](https://qiita.com/LittleWat/items/4681fd12140ac05ad385)の1人マーティン・ファウラーによるリファクタリング本第2版（部分的にケント・ベックも参加）。一般に「リファクタリング本」と言えばこの本の事を指すくらい有名な名著。リファクタリングの概要・適用すべきポイント・適用方法等が具体的に説明されていてわかりやすい

https://learning.oreilly.com/library/view/refactoring-improving-the/9780134757681/

## なんで第2章なのか？
- 本書の構成は以下のようになっています。下記の通り第2章が個人的に分かりにくかったためまとめています

|章|概要|まとめるべきかどうか|
|:--:|:--|:--|
|第1章|リファクタリングの実例を通してリファクタリングの **雰囲気をつかむ**|✖本章の内容は書籍を見ないと要点はつかめないかと思いました|
|第2章|リファクタリングの定義やメリット、いつリファクタリングすべきか等といった **リファクタリングの基本** を紹介|🔵読み物風に書かれており要点がつかみにくかったため本記事でまとめ直そうと思いました|
|第3章|より具体的に **どのようなコードに対してどのようなリファクタリングを適用すべきか** を紹介|✖[REFACTORING・GURU](https://refactoring.guru/refactoring/smells)のまとめが良くできていたのでそちらを読んでいただいたほうが良いかと思います|
|第4章|リファクタリングと一緒に **使用が必須な技術でもあるテスト(特にTDD)について** 簡単に例を通して紹介|✖必須技術なので紹介されていますが、本書はテスト本でもないので深くは書かれていたいため特にまとめる必要はないと感じました。|
|第5章以降|**リファクタリングカタログ** を掲載|✖書籍の記載が非常にわかりやすく、まとめる必要もないほどです（図による解説、サンプルコード、動機、適用方法と項目が分かれており、理解しやすいです）。<br/>[REFACTORING・GURU](https://refactoring.guru/refactoring/techniques)のまとめもおススメです|

## 免責
- 本記事のまとめは私が理解した内容を基にまとめているため、書籍の構成と一部異なる点や抜け漏れがあります
- 書籍に含まれていない関連する内容を追加している箇所がいくつかあります
## 第2章「リファクタリングの原則」
### 概要
そもそもリファクタリングとは何か？どういうときにリファクタリングすべきか？など、リファクタリングの基本原則を紹介する
### 内容
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/ee4598d2-83ce-bc2b-b2df-5276737a9a80.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/e0427ef4-fd7d-389a-2893-67f9c9cfba51.png)

- リファクタリングの定義
  - ソフトウェアの動作は変えずに内部構造を変えて理解しやすく変更を容易にする(もしくはその事)
    - つまり、リファクタリング中は **機能追加しない**
- リファクタリングの利点
  - コード品質向上（割れ窓対策、DRY原則準拠等）
  - コードが読みやすくなる
  - バグが見つけやすくなる
  - (長期的に見れば)高速化しやすくなる
- リファクタリング開始のサイン
  - 似たようなことを行ったとき(３ストライク)
  - 新機能実装前
  - コードの理解を頭の中で形成したとき(パッと見で理解できないコードに出くわしたとき)
- リファクタリング推奨事項
  - 数週間を要する大規模のリファクタリングの場合、小さいリファクタリングを散発的に適用していく事で対処可能(例：[mf-bba等](https://martinfowler.com/bliki/BranchByAbstraction.html))
  - コードは特定の人物が独占するのではなく、チームメンバーからもプルリクを出せるようにする
  - <img width="512" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/6f42dcd9-1f5d-e452-3ca5-ceaf35589fb6.png">

  - 開発ブランチとリファクタリングブランチを分けるべきではない(サクッとリファクタリングしずらくなる。ただしCIを導入してバグ混入を監視している前提）
  - テストは自己テストコード必須([mf-stc](https://martinfowler.com/bliki/SelfTestingCode.html) (Unitテストとほぼ同義？))
  - 古いコードもリファクタリング対象となり得る
    - まずはテストを追加する(ただ一筋縄にはいかない
      - [名著](https://learning.oreilly.com/library/view/working-effectively-with/0131177052/)があるので詳しくはそちらを参照)
      - https://learning.oreilly.com/library/view/working-effectively-with/0131177052/
    - 良く扱う箇所から段階的にリファクタリングする
  - データベースのリファクタリング
    - データと呼び出し元コードが分散しており難しい（密結合／影響範囲が広い）
    - リファクタリング後にシステムが正しく動くことを確認する必要がある
    - コミットを細かく切るのをお勧め
    - <img width="512" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/1cd8b9b5-a832-a8b6-3968-ebca1c60af77.png">
- SWの柔軟性
  - 将来書いてるコードに対するニーズが変わった時に向けてコードに柔軟性を持たせるかどうか
    - リファクタリングするのが難しそうな場合のみ柔軟性を持たせる
    - それ以外は[yagniの法則](https://martinfowler.com/bliki/Yagni.html)を適用する(今いらない機能は持たせない)
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406339/834a99f8-6433-5d9e-1161-60a9085dead8.png)

- リファクタリングはXPの一部として発生してきた
- 3種の神器「自己テスト」「リファクタリング」「CI」
  - これが無いと上記のyagniは実践できない
- リファクタリングとパフォーマンスの影響
  - 一時的に性能低下する可能性はあるが、パフォーマンスチューニングしやすくなる
  - パフォーマンスに影響するコードは全体の10%に集中しがち(パレートの法則)
    - 問題になるまでパフォーマンスよりもプログラム構造の良さを追求、そして必要になったらその10%をチューニングする方が早く高速化できる
    - 
### 【参考】IDEのリファクタリング支援機能例
最近のほとんどのIDEでは関数の抽出などリファクタリングを支援する便利な機能がついています。
テストスイートと並んで共に快適にリファクタリングを行うための必須機能の一つです。

#### VSCode(python/Java/PHP/SCSS等)

https://code.visualstudio.com/docs/editor/refactoring

#### Visual studio(C#/VB/python/C++)

https://docs.microsoft.com/ja-jp/visualstudio/ide/refactoring-in-visual-studio?view=vs-2022

https://docs.microsoft.com/ja-jp/visualstudio/python/refactoring-python-code?view=vs-2022

https://docs.microsoft.com/ja-jp/cpp/ide/writing-and-refactoring-code-cpp?view=msvc-170