私は、他の開発者がどのようにリファクタリングを開始したのか疑問に思っていました。あなたの最初のステップは何ですか?自分のものではないコードをリファクタリングした場合、このプロセス (リファクタリング) はどのように異なりますか? リファクタリング中にテストを作成しますか?
14 に答える
- 単体テストがまだない重要なものはリファクタリングしないでください
- 単体テストを書いてからリファクタリングする
- 小さな部分をリファクタリングし、テストを頻繁に再実行する
- コードが DRY * cleanの場合はリファクタリングを停止します
* DRY = 繰り返すな
あなたの最初のステップは何ですか?
最初のステップは、単体テストを実行して、すべてが合格することを確認することです。実際、コードを変更する前にテストが壊れていた場合、どの変更がテストを壊したかを探すのに多くの時間を浪費する可能性があります。
あなたのものではないコードをリファクタリングした場合、このプロセスはどのように異なりますか?
私が書いていないコード (またはずっと前に書いたコード) をリファクタリングするとき、私は確かに小さなステップを実行しています。また、続行する前にテスト カバレッジを確認して、常に合格する単体テストに依存することを避けることもできますが、作業中の領域はテストされません。
リファクタリング中にテストを作成しますか?
私は通常そうしませんが、次の状況では新しいテストを追加することがあります (すべてを網羅しているわけではありません)。
- 新しいテストのアイデアが頭の中にひらめきます ( 「…だったらどうなるの?」 - テストを書いて知る)
- テストカバレッジの穴を発見
また、実行中のリファクタリングにも依存します。関数を抽出するときに、以前とは異なる方法で呼び出すことができる場合は、新しいテストを作成することがあります。
一般的なアドバイスを次に示します。
まず、コードの作業中に気付いたコードの臭いのリストを維持することです。これにより、コードで見たものを思い出す負担から心を解放できます。また、
ゴールデン ルールは、単体テストが完全にパスしない場合は決してリファクタリングしません。
コードが安定したらリファクタリングし、将来のリファクタリングによって影響を受けることがわかっているものを追加する前に、統合する前に、そして何よりも完了を言う前に。
単体テストがない場合は、リファクタリングするコードの部分をテスト対象にする必要があります。よくあることですが、単体テストをレトロフィットするのが難しすぎる場合は、Michael Feathers in Working Effectively with Legacy Codeで推奨されているように、特性化テストを作成できます。つまり、コードの現在の動作を特定できるエンド ツー エンドのテストです (常に完全に機能しているとは限りません)。
赤ちゃんの一歩を踏み出すことを恐れないでください。2 つのことを同時に行わないでください。リファクタリングが必要なことを指摘した場合は、それを書き留めてください。たとえそれが非常に簡単に思えても、すぐには修正しないでください。
テストに合格したら、頻繁にチェックインします。以前に行ったことを失うことなく、悪いリファクタリングを元に戻すことができるようにします。
リファクタリングは顧客に価値をもたらさないことに注意してください (これについては議論することができます)。経験則の 1 つは、コードに変更を加えたり新しい機能を追加したりする前にリファクタリングすることです。
私はがらくたを取り、それをより少なくします。:-)
真剣に。新しい機能を作成するためのリファクタリングは行いません。リファクタリングは、新しいものの前に発生します。テストがない場合は、リファクタリングで何かを壊していないことを確認するためにテストを作成します。テストがある場合は、それらを使用します。テストが不十分な場合は、さらにテストを作成することもありますが、これはリファクタリングとは別に考えて、最初に行います。
私にとっての最初のステップは、何かを抽象化してより一般的なものにする (そして、その機能が必要な他の場所で役立つようにする) ことができることに気付くことです。私は理由もなく一般性にリファクタリングしません。 YAGNI 原則が適用されます。
私たちは所有権を共有するという概念を持っているので、コードは常に私のものです。目的が明確でない場合、リファクタリングが必要であると判断する前に、物事を理解しようとすることがありますが、ほとんどの場合、それ自体がリファクタリングを行う理由になります。
Martin Fowlerの著書「Refactoring」を読む
ところで - ご参考までに、これは Martin Fowler 自身の Amazon exec リンクです :)
私の目標に大きく依存します。すでに述べたように、リファクタリングによって何も壊れていないことを確認するために単体テストが必要です。壊れている場合は、時間をかけて修正する必要があります。多くの状況で、既存のソリューションをテストし、機能する場合は、リファクタリングするのではなくラップします。これにより、破損の可能性が最小限に抑えられます。
たとえば、最近 ASCII ベースの C++ を UNICODE に移植する必要があった場合など、リファクタリングが必要な場合は、ユニット レベルだけでなくエンド ユーザーでも機能する優れた回帰テストを用意するようにしています。繰り返しになりますが、手動でリファクタリングするのではなく、ツールを使用するようにしています。これは、エラーが発生しにくく、発生するエラーがランダムではなく体系的であるためです。
私にとって最初のことは、コードが私たちのオフィスのすべてのベストプラクティスに適合していることを確認することです. たとえば、Perl スクリプトに strict、warning、および taint を使用しています。
効率や速度の問題がある場合は、それらに焦点を当てます。より良いアルゴリズムを見つけたり、4 重にネストされた for ループが行っていることを行うためのより良い方法を見つけたりします。
最後に、コードをより読みやすくする方法があるかどうかを確認します。これは通常、同様のことを行う 5 つの小さなスクリプトを 1 つのモジュール (クラス) に変換することによって実現されます。
単体テストを使用して、新しいコードを作成しながらリファクタリングします。また、メソッドが長すぎる場合、または変数の名前が不適切である場合、または重複などを見つけた場合は、古いコードをリファクタリングします。
単体テストの取得から始めて、自動リファクタリング ツールを使用します。リファクタリングを自動化できない場合、それは実際にはコードの機械的な変換ではなく、リファクタリングではありません。単体テストは、あるコードベースから同等のコードベースへの機械的な変換を実行しているだけであることを確認するためのものです。
単体テストなしのリファクタリングは危険です。常に単体テストを行います。適切なテストを行わずに何かを変更した場合、コードの一部は安全かもしれませんが、他の部分は同じ動作をしない可能性があります。単体テストを使用すると、変更を保護できます。
他のコードのリファクタリングも問題ありませんが、極端な場合はそうではありません。他の誰かがあなたのようにプログラミングしないのは普通のことです。あなたが他の方法でそれをしたからといって、物事を変えるのは「親切」ではありません。本当に必要な場合はリファクタリングするだけです。
重複を取り除き、コードに固有の思考パターンを統一します。リファクタリングでは、これら 2 つのことを達成する必要があります。同じことを 2 回行うコードがある場合は、共通の場所にリファクタリングして、抽象化を統一します。同じリテラルが 3 か所ある場合は、定数に入れ、目的を統一します。引数のグループが同じ場合は、それらが常に同じ順序で使用されることを確認するか、さらに良いのは、情報グループを統一する共通の構造にそれらを配置することです。
私は、自分のコードをリファクタリングするよりも、他の人が書いたコードをリファクタリングすることに消極的です。
私の前任者の 1 人によって書かれた場合、私は通常、関数内でのみリファクタリングします。たとえば、if ステートメントをスイッチに置き換えることができます。それよりもはるかに大きなものは通常、範囲外であり、予算内ではありません。
私自身のコードでは、何かが醜く見えたり、においがし始めたりするたびに、書いているときに通常リファクタリングします。後で問題が発生するのを待つよりも、今すぐ修正する方がはるかに簡単です。
あなたが書いたコードをリファクタリングしているとき、私は他のポスターに同意します。
自分が書いたものではないコードの場合、特に大量のコードがある場合は、fxCop、Visual Studio のコード分析、DevPartner などのツールを使用することから始めます。他にも優れたツールがあるはずです。どこから始めるべきか、最も一般的なコーディングの問題は何かについてのアイデアを提供してくれます。また、ストレス テストを行って、ボトルネックがどこにあるかを確認します。これにより、コードを改善する努力に対する最大の見返りが得られます。
私は自分のコードをリファクタリングするのが大好きですが、やりすぎる可能性があります。アプリのパフォーマンスを実際に改善していない場合、またはコードの読みやすさを真剣に改善していない場合は、おそらく停止する必要があります。特に単体テストを行わずに作業している場合は、リファクタリング時に新しいバグが発生する可能性が常にあります。
最初のステップ:コードの臭いを特定します。
2番目のステップ:代替の実装と、トレードオフとは何か、そしてどちらが「より良い」かという点でどちらを受け入れるかを検討します。
3番目のステップ:より良いソリューションを実装します。
コードが私のものであるかどうかにかかわらず、これは違いはありません。数か月または数年前に書いたコードに戻って、他の誰かのコードのように見えることがあるからです。新しいメソッドを作成している場合、またはコードIMOに適切なテストがない場合は、テストを作成することがあります。