「レガシーコードで効果的に作業する」という本を何度か推奨しています。この本のキーポイントは何ですか?
ユニット/統合テストを追加してからリファクタリングすることよりも、レガシーコードを扱うことのほうがはるかに多いですか?
「レガシーコードで効果的に作業する」という本を何度か推奨しています。この本のキーポイントは何ですか?
ユニット/統合テストを追加してからリファクタリングすることよりも、レガシーコードを扱うことのほうがはるかに多いですか?
回答:
レガシーコードの主な問題は、テストがないことです。そのため、いくつか追加する必要があります(さらに...)。
@mattnzが指摘したように、これ自体は多くの作業を必要とします。しかし、レガシーコードの特別な問題は、テスト可能なように設計されていないことです。そのため、通常は、複雑なスパゲッティコードが複雑に絡み合っており、ユニットテストの対象となる小さな部品を分離することは非常に困難またはまったく不可能です。そのため、単体テストの前に、コードをリファクタリングして、テストしやすくする必要があります。
ただし、安全にリファクタリングするには、変更で何も破損していないことを確認する単体テストが必要です。これはレガシーコードのキャッチ22です。
この本は、最初の単体テストを有効にするためだけに、コードに絶対的に最小限の、最も安全な変更を加えることにより、このキャッチを打開する方法を教えます。これらは、デザインをより良くするためのものではなく、ユニットテストを有効にするためだけのものです。実際、設計がより複雑になったり、より複雑になったりすることがあります。ただし、これらを使用するとテストを作成できます。ユニットテストを実施したら、自由に設計を改善できます。
コードをテスト可能にするための多くのトリックがあります-ある種の明白なものもあれば、まったくないものもあります。本を読まなければ、自分自身について考えたことのない方法があります。しかし、さらに重要なことは、Feathers がコードユニットを正確にテスト可能にするものを説明していることです。依存関係をカットし、コードに障壁を導入する必要がありますが、次の2つの明確な理由があります。
依存関係を安全に切断するのは難しい場合があります。インターフェース、モック、依存性注入の導入は目標としてクリーンで素晴らしいものですが、この時点では必ずしも安全ではありません。そのため、通常は、たとえばDBへの直接リクエストを開始するメソッドをオーバーライドするために、テスト対象のクラスをサブクラス化する必要がある場合があります。また、テスト環境で依存クラス/ jarを偽のクラス/ jarに置き換える必要がある場合もあります...
私にとって、フェザーによってもたらされる最も重要な概念は縫い目です。シームは、コード自体を変更せずにプログラムの動作を変更できるコード内の場所です。コードに継ぎ目を構築すると、テスト対象のコードを分離できますが、直接実行することが困難または不可能な場合でも、テスト中のコードの動作を感知することもできます(たとえば、呼び出しが別のオブジェクトまたはサブシステムに変更を加えるため) 、その状態はテストメソッド内から直接クエリすることはできません)。
この知識により、最も厄介なコードヒープ内のテスト容易性の種に気づき、そこに到達するための最小限の、中断を伴わない、最も安全な変更を見つけることができます。言い換えれば、気付かないうちにコードを壊すリスクがある「明白な」リファクタリングを避けるために-それを検出するための単体テストがまだないので。
レガシーコードを効果的に使用するための重要なポイントをすばやく取得する方法
私は1980年代に遡る数百万行のコードのコードベースに取り組んでいます。それは単なるソフトウェアですので、いくつかの単体テストを書くだけの問題なので、あなたはそれをリファクタリングして、より良くすることができます。
ここでのキーワードはただです-それは、どのようなプログラマーの語彙にも属さない4文字の言葉であり、レガシーシステムで作業している人は言うまでもありません。
単体テストを作成し、1時間分の開発作業をテストするのにどれくらい時間がかかると思いますか?議論のために、もう一時間言ってみましょう。
20万年前の100万行のレガシーシステムにどれだけの時間を投資していますか?たとえば、20年の開発者20人が2000時間/年(彼らはかなり一生懸命働いた)としましょう。数を選んでみましょう-新しいコンピューターと新しいツールがあり、あなたはそもそもこの$%^^の部分を書いた人たちよりもはるかに賢いです-あなたはそれらの10の価値があるとしましょう。あなたは40人年も持っていますか?
したがって、あなたの質問に対する答えはもっとたくさんあります。たとえば、1000行(5000行を超える行がいくつかあります)のルーチンは、非常に複雑で、スパゲッティの一部です。(さらに4文字の単語で)数日で数百行のルーチンと数20行のヘルパーにリファクタリングできますよね?違う。これらの1000行には、100のバグ修正が隠されています。各バグ修正は、文書化されていないユーザーの要件または不明瞭なケースです。元の100行のルーチンではジョブが実行されなかったため、1000行です。
あなたは「それが壊れていないなら、それを修正しないでください」という考え方で作業する必要があります。破損した場合は、修正するときに非常に注意する必要があります-改善するにつれて、誤って何かを変更しないようにします。「壊れた」には、システムとその使用法に依存する、保守できないが正常に動作するコードが含まれる場合があることに注意してください。「私がこれを台無しにして悪化させたらどうなるか」と尋ねてください。なぜなら、いつかあなたはそうするでしょうし、なぜあなたがそれをすることを選んだのかを上司に伝える必要があるからです。
これらのシステムはいつでも改善できます。仕事の予算、タイムラインなどがあります。そうでない場合-行って作ります。お金/時間がなくなったら、それを改善するのを止めてください。機能を追加し、それを少し良くする時間を与えてください。バグを修正します-もう一度、少し余分な時間を費やして改善します。開始時よりも悪い状態で配信しないでください。
本から取り上げる2つの重要なポイントがあります。
他のレスポンダーが指摘しているように、既存のレガシーコードを先制的に更新しようとするのはばかです。代わりに、(新しい機能またはバグ修正のために)レガシーコードに変更を加える必要があるときはいつでも、レガシーステータスを削除するために時間をかけてください。