リファクタリング

■リファクタリング

リファクタリングとはXPのプラクティスの一つです。
「リファクタリングする」は「コードをきれいにする」と同義で使用されています。
厳密には「コードの外部から見た動作を変えることなく、コードの内部を整理整頓する」ことです。
リファクタリングによりコードの保守性が向上し、将来的な拡張や修正が行いやすくなります。

	保守性:
		保守性とはシステムの維持や管理のしやすさのこと
		保守性が高いほどバグの発見や修正、新規機能の追加も行いやすい

●技術的負債
	コードには「きれいなコード」と「汚いコード」が存在します。
	プログラマーは常にきれいなコードを書こうとしますが、
	状況がそれを許さないことがあります。
		
		例:
			・想定外の仕様変更、追加が発生
			・時間がなく、とりあえずの動作を目標とする
			・他の人が保守性を考慮したコードを書いていない

	こういったケースで書かれたコードは保守性が低く、きれいなコードとは呼べません。
	近年ではきれいなコードに対して将来的な価値があるとは考えず、
	汚いコードに対して負債があるという考え方もあります。
	なぜ負債と考えるかというと負債には利息がつき、返さないとどんどん大きくなっていきます。
	汚いコードもどこかで手を入れないとどんどん修正が難しくなっていくために
	「汚いコード = 負債」という考えが誕生しました。
	リファクタリングはこの負債を返済するための方法です。

■リファクタリング箇所と修正

●リファクタリング箇所の内容
	リファクタリングを行ったほうがいいと考えられている箇所は
	以下のようなものが挙げられます。

	pgtheory_0032

	上記の内容は一例です。
	また、「リファクタリング対象」 = 「修正箇所」ではありません。
	リファクタリング対象となっている箇所に後々問題となりうる内容が多いというだけです。
	例えばゲームのRPGでプレイヤーと敵のダメージ処理が同じ内容だったとします。
	その場合、リファクタリング対象の「重複コード」にあたるので、
	ダメージ処理を共通の関数化して使用することを考えます。
	しかし、後々のバージョンアップでプレイヤーと敵のダメージ処理が異なるものになることが
	判明している場合、ここで重複コードとして修正する必要はありません。

●リファクタリング箇所の修正
	リファクタリング箇所を修正する場合の方法は以下のようなものが挙げられます。

	pgtheory_0033

	マジックナンバーの変更などの比較的影響が狭い内容から
	クラス新規作成などの影響範囲が広い箇所まで色々とありますが、
	全てを一度に行わないようにしてください。
	後述するリファクタリングの注意点で書きますが、
	リファクタリングする際は変更内容を細分化し、
	細かい単位で修正とテストを繰り返しながら行っていきます。
	一度に複数の箇所を修正した結果、動作しなくなったとなると
	その間の作業時間の無駄です。
	ですので、手間がかかったとしても修正とテストを繰り返しながら
	リファクタリングを行っていきます。

■リファクタリングの注意点

●テストを必ず行う
	リファクタリングを行うとデグレードが発生するリスクがあります。
	それを回避するにはリファクタリング中に頻繁にテストを行う必要があります。
	リファクタリング作業内容を作成して、
	一つの作業が終了したらテストを行い、デグレードが発生していないことを確認します。
	この作業についても大規模な作業になるようだったら細分化して
	リスクを分散させるべきです。

	デグレード:
		デグレードとはソフトウェアの品質が以前より落ちてしまうこと。
		以前に修正されていたバグが再発したり、
		動作していたはずの箇所が動かなくなること

●機能追加は同時にしない
	リファクタリングと機能追加は同時に行ってはいけません。
	リファクタリングの規模が小さいからと同時に機能追加を行った際に
	バグが発生したらそれはリファクタリングによるものか
	機能追加によるものか、それとも両方の要素が重なったものか分かりません。
	原因の把握に時間がとられてしまいます。
	リファクタリングはリファクタリング、機能追加は機能追加と
	作業のタイミングを分けて作業を行ってください。

●柔軟性は求めすぎない
	リファクタリングは保守性を上げるために行いますが、
	修正の際にコードに柔軟性を求めすぎてはいけません。
	きれいでメンテナンスしやすいコードとはあらゆる変更を想定したコードではありません。
	その時の仕様についてシンプルに実装されているコードが
	きれいなコードとされています。
	将来的な内容を見越した設計はリファクタリングの対象となりますので、注意が必要です。

●期間を決める
	リファクタリングを行う場合、期間を決めてその間やるようにして下さい。
	完璧なきれいなコードを目指そうとすると何時までたっても終わらなくなります。
	リファクタリングは外から見た動作は変えず中だけを整理整頓します。
	それは「外側の動作が変わらない = 目に見える機能が追加がない」ということなので
	クライアントからの評価が上がることはありません。
	彼らが欲しているのは様々な機能が動作するソフトであり、
	保守性の大切さを訴えたとしても理解を得れる可能性は低いです。
	クライアントの評価を落とさないレベルでリファクタリングの期間を設け、
	より良いソフトウェアを開発して下さい。

■リファクタリングのタイミング

リファクタリングのタイミングは以下の4つが考えられます。
これらの中から自分たちのプロジェクトに適したタイミングを考え
リファクタリングを行いきれいなコードを目指してください。

●テスト駆動の一環
	テスト駆動(TDD)開発では作業の流れの中にリファクタリングの期間が設けられています。
	ToDo失敗(レッド) => ToDo成功(グリーン) => リファクタリング(リファクタリング)の流れを
	繰り返しながら開発が進んでいくので、TDDでは保守性の高いコードが期待できます。

●プロジェクトの終盤
	プロジェクトの終盤やある程度まとまった機能が実装された後に
	リファクタリングを行います。
	コードの負債は細かく返していくのが理想ですが、
	実装内容によっては中々手をつけられない状況があると思うので、
	プロジェクトの終盤でチーム全体で品質保証、向上の一環として
	リファクタリング作業を行います。

●リファクタリングの期間を設ける
	週1日や隔週に1日などリファクタリングを行う日を設定し、
	その日はリファクタリングを行うようにします。
	もちろん、作業の進行具合で日にちがずれることはあると思いますが、
	その辺りは臨機応変に対応します。

●機能追加の前
	機能追加の前後のどちらかでリファクタリングの期間を設定するとしたら
	追加の前で行ってください。
	この時のリファクタリングでは新しく追加する機能を実装する前提で、
	コードを確認していきます。
	もし、機能追加しづらい箇所があった場合、追加内容に合わせて
	コードをリファクタリングします。
	これによって、この後に行う機能追加がスムーズになるので、作業効率も上がります。