#book #r2021 ![image](https://gyazo.com/ca2180d31297bc62fa6516eacf8c7815/thumb/1000) > Refactoring is the process by which was restucture exisiting code without changing its external behaviour. > リファクタリングとは、システムの外部挙動を変えずにコードを修正することである。 # 概要 ## Bnefits of Refactoring - Developer Productivity - コードベースが大きくなればコードの全てを把握するのは不可能 - 把握するためには読む必要が出てくる - 新たな人が入るときの立ち上げを早くする - Identifying bugs - コード全体を読みやすくすることでbugを探しやすくる、直しやすくする ## Risks of Refactoring - 「システムの外部挙動を変えずに」というのは、言うほど簡単ではない - 当然ながらいくつかのリスクが存在する - Serious Regression - 元々のバグだったとしても、システムの外部挙動が変わってしまう場合には、デグレと言える - 最も大きなリスクの1つはこのデグレが起こることである - Unearthing dormant bugs - 今まで問題になっていなかったような問題がリファクタリングを通して問題になることもある - 例えば構造上の問題などである - Scope Creep - リファクタリングのゴールを決めることは重要 - さもなければ永遠にできてしまう - Unnecessary Complexity - 最初の想定よりもコードが複雑になっている場合もある - 最初のゴールを柔軟に変えることが重要 ## When to Refactor - 具体的な基準点などを設けて、いつ取り掛かるかを定めるのは難しいが参考になる観点を考える - Small Scope - 範囲が小さくて、十分なテストがある場合には問題なくやってしまえばいい - Code Complexity Actively Hinders Development - 開発者がある部分のコードを触れなくなってしまっている場合 - Shift in Product Requirements - 要求が変わるときには、それに合わせてリファクタリングができる場合がある - Performance - パフォーマンスの劣化がある場合にリファクタリングした方がいい場合がある - Using a New Technology - 新しいライブラリなどを導入する際にそれに合わせてリファクタリングした方がいい場合がある ## When not to Refactor - For fun or out of boredom - リファクタリングは、趣味や片手間ですべきではない - 小さい変更で最大のメリットを享受するのがリファクタリングなのでゴールを決めて評価する準備をした上で取り組むべきである - Becuase you happened to be passing by - 見かけたから修正と言うには、やめる - 大抵の場合には、背景などを十分に理解しないままリファクタリングをすることになってしまう - To making code more extendable - 明確な課題やゴールがないまま読みやすくするという意図でのリファクタリングは避ける - 未来を正しく予測できずにコストが無駄になりかねない - When you don'thave time - 中途半端なリファクタリングされたコードほど読みにくいものはない # How Code Degrades 主に2つの要因がある。それが「技術負債」と「要求の変更」である。 ここで注目したいのは、必ずしも技術負債だけがコードの品質を下げるわけじゃないという点である。 ## Requirment Shifts 要求の変化の観点としていくつかある。どれもその時点と今では状況が違うということに基づいている。基本的には、動いてるコードはその時点ではベストな選択だったと理解する必要がある (そんなこともないかもだけれど) - Scalability - 最初にコードを書いた時からデータの量やユーザー数が変わってるかもしれない - Accessibility - 最初は多くのユーザーを優先するあまりアクセシビリティの優先度を下げるというのはよくある話 - アクセシビリティのクオリティをあげていくにはコードの品質が低いかもしれない - Device Compatibility - 新規に出てきたハードウェアに合わせたり - 新しい機能に合わせたり - Environmental Change - 新しい攻撃手法やユーザー、社会の環境の変化による影響に対してコードの品質が耐えれなくなってる - External Dependensies - 言語のアップデート、新しいOSやライブラリのアップデートなど - アップデートし続けるのが理想だけれどサボってしまい最終的には大ごとになってしまうことがある - Unused Code - 機能を消したけど、時期が来てもコードを消し忘れたりする - 他の開発者が誤ってそのコードを利用したりそもそも削除していいかわからなかったりしてしまう - Changes in Product Requirements - 最初にBooleanフラグ1つだけで対応できていたものが、要求の変化によって他のパターンも扱わないといけなくなる ## Tech Debt ここは、いつもの話で改めて述べることはなかった # Measuring Our Starting State リファクタリングを始める前には、定量的なゴールを設定すべきだがそれは簡単ではない。いくつかの観点にわけて取り上げる。 ## Code Complexity リファクタリングの主な理由はコードの複雑性を下げて、開発者の生産性を上げることである。しかし、この複雑性を測定するのはそんなに簡単ではない。 - Halsted Metrics - 1975年に提案されたメトリクス - オペレーターとオペランドの数によって関数などの複雑どを評価する手法 - 分岐や変数が多ければ多いほどプログラマが関数を理解するのが難しくなるという観測に基づく - ただし近年のプログラムにそのまま適用できるかというと難しい - Cyclomatic Complexity - 1976年に提案されたコントロールフローの数をベースにした測定方法 - ifやforなど分岐の処理が多くなるに連れてプログラマが理解するのが複雑になるという観測に基づく - 言語に依存しないという特徴もあり、よく利用される - NPath Complexity - 1988年にCyclomatic Complexityに対して、ifやforを同じ扱いにしていたり、ネストした分岐を扱えなかったのを扱えるようにしたもの - ただしこの手法は、一般的に計算コストが莫大で大きなソースコードで適用するのは難しい - Lines of Code - Cyclomatic ComplexityやNPath Complexityほど科学的ではないにしろ、コードのサイズを指標にするのも参考になる - 例えば以下の観点 - LOC per Files - Function Length - Average Function Length per File, Module or Class ## Test Coverage テストカバレッジは、ただLineカバレッジを測ればいいわけじゃない 主に以下の2点の観点を気にする - Quantitatively - 測定は簡単でC1、C2、C3を測定すればいい - Qualitatively - テストはカバレッジを満たしつつ、クオリティが高くなければいけない - クオリティが高いテストには以下のような特徴がある - バグを見つけてくれる - 実装に大きく依存しすぎていない - E2Eテストなど様々なタイプのテストの種類がある リファクタリングする際には、十分なテストカバレッジを満たしてから始めるべき。もしもないのであればテストをまず書こう ## Documentation リファクタリングを始めるまえに、ドキュメントを確認しておくことも重要。コードからのみではわからないような情報も得ることができる。 - Formal - アーキテクチャディシジョン - 設計の図 - スタイルガイド - オンボーディング資料 - ポストモーテム - などのドキュメントの形をしているもの - Informal - Chat - Email - Bug Tracking System - などのドキュメントの形をしていないものから得られる情報も多々ある ## Version Controll バージョン管理にある情報もリファクタリングのためには有用だったりもする - Commit Message - Commits in aggregate (集計) - Adam Tornhill の Software Design X-Raysという本でバージョン管理からどういうパターンを見出せるかというのは詳細がかいてあるが以下がサマリー - Change Frequenncies - 変更が多い = 開発者がよく触る -> リファクタリング対象になり得る - tightly-coupled - 同一のコミット内での変更ファイルを見ることで変更に対しての柔軟性を見ることもできる - Commitの粒度が開発者によって異なるなどの注意点はあるので、あくまでも参考の値として留める ## Reputation - リファクタリングによって利益を得るのは開発者なのだから開発者にインタビューなどを通して定性的なデータを集めるのも有効 - いろんな関わり方をしている開発者に対して多角的にインタビューするとより有益になる - にも近い動き [https://www.youtube.com/watch?v=QCRe-Vo-PPo](https://www.youtube.com/watch?v=QCRe-Vo-PPo) # 感想 - 全体的に内容はそんなに深くなかったけど、参照がしっかりしている - 終始リファクタリングは適当にやるべきではなく、明確なゴールを持ってやるべきということを書いていた - リファクタリングは課題あり気で取り組まないとうまくいかないというのもわかるという感じだった - Software Design X-Rayという本が読みたくなった