私は、どこにでもコードが重複しており、明らかにリファクタリングが必要な、本当のネズミの巣である研究コードをいくつか持っています。ただし、テーマの新しいバリエーションを考え出し、それらをコードベースに適合させるにつれて、コードベースは進化しています。私がリファクタリングをこれほど長く先延ばしにしてきた理由は、良い抽象化を考え出すのに数日を費やした瞬間、どのデザインパターンがどこに適合するかを確認するなど、新しい予期せぬアイデアを試してみたいと思うからです。私の抽象化は完全に不十分になります。言い換えれば、コードが進化する速度のせいで、(おおよその) 重複が不足することはなく、コードの一般的な乱雑さにより、何かを追加することが現実的になっているにもかかわらず、抽象化の行がどこに属するのか、私にはまったくわかりません。痛み。
9 に答える
リファクタリングに長い時間を費やす必要はありません。
コードの一部を変更しようとしている場合は、変更を容易にするためにコードをリファクタリングすることを検討してください。
変更を行った後、再度リファクタリングして、その変更によるダメージをクリーンアップします。
どちらの場合も、リファクタリングを小さくして迅速に行い、先に進みます。
コードを常に元の状態に保つ必要はありませんが、適切にファクタリングされたコードがあれば (そしてもちろん、優れた単体テストがあれば)、高速化が容易になることを覚えておいてください。
テスト駆動開発:
赤、緑、リファクタリング。すすぎ、繰り返します。
これはすべてのサイクルのステップの 1 つであるため、通常はマイナーなリファクタリングが大量に行われていることに気付くでしょう。そうあるべきです。
あなたの状況は私にはよく知られています。多くの場合、調査コーディングを行っている間、「正しい」抽象化がどうなるかわかりません。あなたが言うように、新しいアイデアごとに変化する可能性があります。
他のポスターは次のように提案しています。
- 継続的な小さなリファクタリングにより、ネズミの巣のような状況に陥るのを回避できます
- テスト駆動開発。再利用可能な優れた抽象化を見つけるのに役立ちます。TDD はテストではなく、優れた設計を行うことであることに注意することが重要です。
ただし、調査研究コードには別の戦略があります: プロトタイプです。これはあなたが現在行っていることのようです: 概念を証明するためにできるだけ早くコーディングします。それは悪いことではありませんが、プロトタイプは常に使い捨てにする必要があります。必要な入力と知識がすべて得られるまで微調整してから 、コードを破棄して、TDD と継続的なリファクタリング、およびその他すべての「正しいことを行う」戦略からやり直してください。
コードを保持しないでください。何もコピーして貼り付けないでください。それを参照しないでください。新しい知識からやり直してください。
コードを少しずつクリーンアップします。クラスに触れるときは、クラスを触れる前の状態に保つようにしてください ( 「ボーイスカウトのルール」 )。リファクタリングは非常に小さなステップで行うのが最適ですが、非常に頻繁に行います。
変数の名前変更、メソッドの分割などには、数秒または数分しかかかりません。クラスの分割や参加などの大規模なリファクタリングには、1 時間か 2 時間かかる場合があります (そして、すべてのテストが少なくとも 5 分ごとにパスするように、小さなステップで行います。そうしないと、リファクタリング地獄に入り、最後に確認された作業に戻る必要があります。州)。何かをリファクタリングするのに数日または数週間かかる場合、それはもはや「リファクタリング」ではなく、書き直しに似ています。
このトピックに関する記事: http://blog.objectmentor.com/articles/2007/07/20/whats-your-unit-of-measure
少なくともGitのような分散SCMに入れてください。そうすれば、何かのリファクタリングを中断したときに、変更前のコミットを見つけるために時間を割り切れるように逆にすることができ、変更に取り組み、他の作業に干渉することなくブランチでコミットすることができます.
Git Branch のマージは、このような場合に最適です。残りのコードについて心配することなく、2 人のユーザーが並行して互換性のない変更を行ったかどうかを簡単に知ることができます。
上記の理由から、コードをリファクタリングするためだけにリポジトリに別のブランチを作成し、定期的に更新します。このようにして、他の人があなたの進行を妨げないだけでなく、彼らはそれを監視し、最終的にメインブランチにヒットする変更を確認して、それらの変更を先制的にコーディングすることができます.
CloneDRは、大規模なソースシステム全体で、言語構文によってパラメーター化された重複コード(正確なコピーとニアミスの両方)を検出します。Java、C#、COBOL、C ++、PHPおよび他の多くの言語をサポートします。
見つかったクローンのセットのパラメーター化された抽象化を示している場合、基本的には、その抽象化を実装して(メソッド、関数、クラスなどとして)コードをリファクタリングすることを提案しています。
したがって、CloneDRを実行すると、コードに追加される可能性のある抽象化のリストが取得され、クローンインスタンスを抽象化の呼び出しに置き換えると、コードがリファクタリングされて(ある程度)クリーンアップされます。
さらに注目すべきことに、抽象化を呼び出すために必要な各クローンサイトで使用されるパラメーターバインディングを示す場合、バインドされたパラメーターが概念的に矛盾している場合に簡単に認識される、孤立したクローンインスタンスを示すことがよくあります。パラメータがYYYY-MM-DDという名前の変数にバインドされていて、そのうちの1つがYY-MM-DDである場合、「その4桁の年」パラメータタイプは違反しているように見えます。この場合、壊れたY2K修復があります。そのため、クローンバインディングを調べると、バグが見つかることがよくあります。
これは、科学計算で非常に一般的な問題です。コードのサイズと複雑さを減らすための最も効果的なアイデアのいくつかは、仮定を活用する必要があり、科学では、それらの仮定を絶えず変更する必要があります。
あなたができることは、あなたが行くにつれてあなたのコードをリファクタリングしようとすることであり、そしてあなた自身を隅々まで書き込まないようにすることです。また、混乱させないことの価値を理解している善良な人々と協力してください。
書き直しが唯一の選択肢である場合もあります。これは事実のようです。
重複がある場所がすでにわかっている場合は、リファクタリングするのに数日は必要ありません。