リファクタリングすべきか・してよいかの判断基準

 リファクタリングは、設計やコードを綺麗に保つという普遍的に求められる活動の一要素です。常識的な習慣として推進すべき活動です。

 ただ、有効性の理解を得られないままリファクタリングを行って物議を醸す場面も存在します(例えばここのはてなブックマーク等で巻き起こった議論などです)。
 実際、リファクタリングは、以降の保守作業をサポートしてこそ価値がでるものであり、考えなしにいつでも一律実施すればよいというものではありません。リファクタリングの対象やチームの状況によって、リファクタリングをすべきかどうか、線引きがされます。

 このリファクタリングをすべきかどうかの基準ですが、一言でまとめると「妥当な保守性の実現を、妥当な費用対効果で実現できるか」になります。今回はこの基準を構成する「妥当な保守性の実現」と「妥当な費用対効果」について、それぞれ解説します。

リファクタリングで妥当な保守性を実現できるかの基準

 まず「妥当な保守性の実現を、妥当な費用対効果で実現できるか」の前半を構成する、「妥当な保守性を実現できるか」は、リファクタリングが必要となる、有効な保守性要求を満たしているか、というものになります。

 例えば、特定のライブラリの置換が予定されているならば、「そのライブラリ置換を安全に行いたい」という保守性の要求が発生します。その保守性を充足するリファクタリングならば、妥当な保守性を実現できる、と判断できます。
 また、特定のコードの保守作業でミスが頻発しているならば、「ミスを予防する設計構造を実現したい」という保守性の要求が発生します。その要求を満たすリファクタリングも、妥当な保守性を実現する活動です。

 一方で以下に該当するようなリファクタリングは、何かしら有効な保守性要求を充足するものではなく、妥当な保守性を実現していない、と判断されがちです。

  • 十分に枯れていて、今後保守作業が発生する見込みのないコードに対するリファクタリング
  • 独りよがりのこだわりの押し付けで、誰かにとっての保守作業をサポートしないリファクタリング

 このリファクタリングが必要となる、有効な保守性要求についてですが、大きく次の3つに分類できます。

計画上求められる保守性

 計画している保守作業をサポートする保守性の要求です。
 例えば次のような保守性要求が該当します。

  • ソフトウェアアップデートによる機能追加を計画しており、機能追加がしやすいように、設計・コードの変更性を確保したい
  • 自動テストの大規模導入を計画しており、自動テストが導入しやすいようにテスト容易性を確保したい

 このカテゴリの保守性要求に基づくリファクタリングは、開発計画の具体化の中で必要性を識別できます。

リスクマネジメントとして求められる保守性

 プロジェクトリスク・プロダクトリスクの対策として求められる保守性の要求です。

 これは例えば次ような保守性要求が該当します。

  • リソース開放ミスについてリスクが高く、解放忘れを防止する設計を行いたい
  • セキュリティリスクが高い(脆弱性を悪用された時の被害が大きく、かつ脆弱性リスクが高いプロダクトを扱っているなど)ため、脆弱性を埋め込みにくいように設計やコードを改善したい

 このカテゴリの保守性要求に基づくリファクタリングは、リスク分析を通して必要性を識別できます。

日々の開発で求められる保守性

 自分たちが今まさに手掛けている開発作業を支えるための保守性の要求です。
 自分たちチームが開発をしやすいように、自分たちが必要と考える保守性を実現します。テスト駆動開発におけるリファクタリングはここに分類されます。

 このカテゴリの保守性要求に基づくリファクタリングは、自分たちの実感を通して必要性が認識されます。

妥当な費用対効果でリファクタリングできるか

 次に「妥当な保守性の実現を、妥当な費用対効果で実現できるか」の後半を構成する費用対効果についてです。

 保守性の要求があったとしても、その対応の費用対効果がマイナスの場合は、リファクタリングは避けるべき事が多いです。例えば次のような場合です。

  • 自動テストが書かれておらず、リグレッションテストのコストが高くなっている状態では、保守性要求があったとしても費用対効果がマイナスになることがあり、リファクタリングが不適切な場合がある
  • 保守性要求があるとしても、それが独りよがりで有効な要求でなかったら、効果が望めないということで費用対効果がマイナスになる。それに対応するリファクタリングは不要と判断される

 費用対効果は、リファクタリングの費用を安くできるか、リファクタリングの効果が十分かを重視します。これらは、チームやリファクタリング対象の状態を見て判断します。
 例えば対象の自動テストの充実度、自動テストのテスタビリティの高さは、リファクタリングの費用削減に直結します。コードの保守性を日頃から維持・向上するチームの習慣づけができているかも、リファクタリングのとっつきやすさにつながり、費用削減につながります。総合的なプログラミング能力も、費用対効果に連動します。
 これら要素の評価を通して、リファクタリングの費用対効果を評価します。

リファクタリングの必要性をチームに理解してもらうためには

 自分のためのリファクタリングならば、自分が必要・有効だと感じるリファクタリングを個人の習慣として推進するのが基本的な姿勢になります。

 一方でチームとしてリファクタリングを推進した方が良い場合もあります。そこでリファクタリングの必要性をチームに理解してもらうには、前述した保守性要件の分類ごとに応じたアプローチが有効です。次のようなアプローチです。

  • 計画の立案・精査を通して、「計画上求められる保守性」を識別し、それに基づくリファクタリングを推進する
  • プロジェクトリスク・プロダクトリスク分析を通して「リスクマネジメントとして求められる保守性」を識別し、それに基づくリファクタリングを推進する
  • チームの活動を確認したり、レトロスペクティブなどの機会を利用して「日々の開発で求められる保守性」を識別し、それに基づくリファクタリングを推進する

 上記に該当しない保守性要求に基づくリファクタリングは、理解が得られない可能性があり、注意が必要です。具体的には、計画上不要で、リスクコントロールとして求められておらず、開発当事者外の視点から投げかけるようなリファクタリングです。

 なおリファクタリングの必要性をチームに理解してもらう場合での注意点として以下があります。

  • 開発のライフタイムの認識の違い。保守期間を短く考えている人(例えば短期案件として開発にかかわる外部要員等)は、保守期間を長く考えている人と比べて、保守性要求を重視しないことがある。その場合、長いライフタイムで求められる保守性要求を明示化して製品要件として実現を要求する、といった工夫が求められる
  • 必要なコードの保守性の認識の違い。コードの保守性をないがしろにしている人は、そうでない人と比べて、保守性要求の必要性を認識しないことがある。その場合、チームのプログラミングレベルの向上といった啓蒙が求められる