WHITEPLUS TechBlog

株式会社ホワイトプラスのエンジニアによる開発ブログです。

リファクタリングの道しるべ:依存関係を理解して効率的に学ぶ

こんにちは!
ホワイトプラスのコアシステム開発Gエンジニアのさとうです。

プロダクトコードの改善や技術的負債の返済に役立てようと、書籍「リファクタリング 既存のコードを安全に改善する」を読みました。
これまでリファクタリングという大きなくくりでしか認識できていなかったものが、細かく手法として分解されて行動に移せる単位に変化するきっかけとなる良書でした。

この書籍を一通り読み終えて分かったことがあります。
それは、リファクタリング手法に依存関係があるということです。
(例えば「フェーズの分離」というリファクタリングを行う上で、「関数の抽出」というリファクタリングを使うといったように。)
依存関係を考慮した順で学習できたら、もっと理解が深まったかもしれないです…

ということで、この記事ではこれから「リファクタリング 既存のコードを安全に改善する」を学習する方に向けて、リファクタリングの依存関係を紹介し、依存関係を考慮した学習順序をお伝えできればと思います。

リファクタリングの依存関係

リファクタリング 既存のコードを安全に改善する」では、第6章以降にリファクタリングのカタログとして61種類のリファクタリング手法が掲載されています。
各リファクタリング手法(依存元)の説明に記載されている「手順」の項目内で出現するリファクタリング手法を依存先として依存関係の整理を試みました。

百聞は一見にしかずということで、依存関係をmermaid記法で図示したところ、下記のような結果になりました。

リファクタリング手法の依存関係

数が多いこともあり、だいぶ複雑に見えますね…!

図からは「関数の抽出」や「関数宣言の変更」、「関数のインライン化」あたりは大元の依存先になっていることが多く、重要なリファクタリング手法であることが見て取れます。
「変数の分離」や「問い合わせと更新の分離」、「変数のインライン化」などは重要なリファクタリング手法から依存があり、自身は依存しているものがないので早めに押さえておくことで活躍の場が多そうです。

数の割に循環している部分は少なく、依存関係を考慮して順に並べることもできそうですね。

依存関係を考慮した学習順序

ここからは依存関係を考慮した学習順序を求めてみましょう。
依存関係を考慮して順序を決めるアルゴリズムにトポロジカルソートがあります。
トポロジカルソートは、ループのない有向グラフで順序を決めることができます。
前掲の図では

  • 変数のカプセル化 → レコードのカプセル化 → 変数のカプセル化
  • 変数のカプセル化 → レコードのカプセル化 → コレクションのカプセル化 → 変数のカプセル化
  • 関数宣言の変更 → 関数宣言の変更

の3つのループが存在したので、一旦これらを取り除いてトポロジカルソートにかけてみました。
(トポロジカルソートは ChatGPT と一緒に作成しました。
 弊社の ChatGPT の導入については「全エンジニアを対象としてGitHub CopilotとChatGPTを導入しました - WHITEPLUS TechBlog」の記事をご覧ください。)

結果、下記のような順序が提示されました。

  1. 変数のインライン化
  2. 問い合わせと更新の分離
  3. 関数呼び出しによるインラインコードの置き換え
  4. 問い合わせによる一時変数の置き換え
  5. 変数の分離
  6. 関数のインライン化
  7. 関数の抽出
  8. 関数宣言の変更
  9. setterの削除
  10. コレクションのカプセル化
  11. レコードのカプセル化
  12. フィールド名の変更
  13. メソッドの引き上げ
  14. ステートメントのスライド
  15. 関数の移動
  16. パラメータオブジェクトの導入
  17. デッドコードの削除
  18. ファクトリ関数によるコンストラクタの置き換え
  19. メソッドの押し下げ
  20. フィールドの押し下げ
  21. フィールドの引き上げ
  22. コンストラクタ本体の引き上げ
  23. ポリモーフィズムによる条件記述の置き換え
  24. 変数の抽出
  25. 条件記述の分解
  26. 関数群の変換への集約
  27. 関数群のクラスへの集約
  28. 条件記述の統合
  29. 変数のカプセル化
  30. アサーションの導入
  31. 参照から値への変更
  32. フィールドの移動
  33. 値から参照への変更
  34. ステートメントの呼び出し側への移動
  35. 委譲によるスーパークラスの置き換え
  36. 委譲によるサブクラスの置き換え
  37. クラス階層の平坦化
  38. スーパークラスの抽出
  39. サブクラスの削除
  40. サブクラスによるタイプコードの置き換え
  41. 関数のコマンドによる置き換え
  42. コマンドによる関数の置き換え
  43. パラメータによる問い合わせの置き換え
  44. 問い合わせによるパラメータの置き換え
  45. オブジェクトそのものの受け渡し
  46. フラグパラメータの削除
  47. パラメータによる関数の統合
  48. 特殊ケースの導入
  49. ガード節による入れ子の条件記述の置き換え
  50. 問い合わせによる導出変数の置き換え
  51. パイプラインによるループの置き換え
  52. ループの分離
  53. ステートメントの関数内への移動
  54. アルゴリズムの置き換え
  55. 仲介人の除去
  56. 委譲の隠蔽
  57. クラスのインライン化
  58. クラスの抽出
  59. オブジェクトによるプリミティブの置き換え
  60. フェーズの分離
  61. 変数名の変更

この順番で読み進めれば、まだ知らないリファクタリング手法が出てくることは少なくなります!
あくまで、リファクタリング手法の「手順」に記載されていたもののみを抽出したので、「例」に未習のリファクタリング手法が出てくることはあります…

まとめ:リファクタリングの依存関係を把握してスムーズに学習しよう!

この記事では、書籍「リファクタリング 既存のコードを安全に改善する」に記載されているリファクタリング手法について、それらの依存関係と依存関係をふまえた学習順序をご紹介しました。
数も多く、前に学習したものを忘れがちですが、依存関係を把握して学習することで、よりスムーズにリファクタリング手法を身につけることができると思います。
ぜひ、参考にしてみてください!

ちなみに、今回読んだ「リファクタリング 既存のコードを安全に改善する」は書籍購入支援制度を利用させていただきました。
今後も知識の吸収・アウトプット・業務への転用を繰り返しながら、より良いサービス開発を行っていければと思います!

さいごに

ホワイトプラスでは、ビジョンバリューに共感していただけるエンジニアを募集しています!
ネットクリーニングの「リネット」など「生活領域×テクノロジー」で事業を展開している会社です。
どんな会社か気になった方はオウンドメディア「ホワプラSTYLE」をぜひご覧ください。
オンラインでカジュアル面談もできますので、ぜひお気軽にお問い合わせください。

採用情報 | 株式会社ホワイトプラス