24

私は、古いシステムを引き継ぐ任務を与えられたジュニア ソフトウェア エンジニアです。私の予備評価に基づくと、このシステムにはいくつかの問題があります。

  1. スパゲッティコード
  2. 反復コード
  3. 10,000 行以上のクラス
  4. log4j を使用した誤用とオーバーログ
  5. 不適切なデータベース テーブルの設計
  6. ソース管理がありません -> このための Subversion をセットアップしました
  7. 書類の紛失 -> コードを読むこと以外は、ビジネス ルールがわかりません

システムの品質を高め、そのような問題を解決するにはどうすればよいですか?静的コード分析ソフトウェアを使用して、悪いコーディング慣行を解決することを考えることができます。

ただし、悪い設計の問題や問題は検出できません。これらの問題を段階的に解決するにはどうすればよいですか?

4

14 に答える 14

16

レガシーコードを効果的に使用する方法を入手して読んでください。それはまさにこの状況に対処します。

他の人もアドバイスしているように、リファクタリングには、堅実な単体テストのセットが必要です。ただし、レガシーコードは、単体テスト可能であるように記述されていないため、通常、単体テストをそのまま行うことは非常に困難です。したがって、最初にリファクタリングして単体テストを許可する必要があります。これにより、リファクタリングを開始できます...悪いキャッチです。

これは本があなたを助けるところです。最小限の、そして可能な限り安全なコード変更で、不適切に設計されたコードユニットをテスト可能にする方法について、多くの実用的なアドバイスを提供します。ここでは自動リファクタリングも役立ちますが、この本には手作業でしか実行できないトリックが記載されています。次に、単体テストの最初のセットが配置されたら、より優れた、より保守しやすいコードに向けて徐々にリファクタリングを開始できます。

更新:レガシーコードを引き継ぐ方法のヒントについては、私の以前の回答が役立つ場合があります。

@Alexが指摘したように、単体テストは、コードの実際の動作を理解して文書化するのにも非常に役立ちます。これは、システムに関するドキュメントが存在しないか、古くなっている場合に特に役立ちます。

于 2010-09-01T13:17:58.687 に答える
14

まず、壊れていないものを修正しないでください。引き継ぐシステムが機能する限り、機能はそのままにしておきます。

しかし、保守性に関しては、システムが明らかに壊れているので、それがあなたが取り組むことです。上記のように、最初にいくつかのテストを作成し、ソースをcvsにバックアップしてから、最初に小さな部分をクリーンアップし、次に大きな部分をクリーンアップすることから始めます。システムがどのように機能するかを十分に理解するまでは、より大きなアーキテクチャの問題を攻撃しないでください。自分でコードに飛び込まない限り、ツールは役に立ちませんが、そうすると、ツールは大いに役立ちます。

「完璧」なものは何もないことを忘れないでください。過度に設計しないでください。KISSとYAGNIの原則に従ってください。

EDIT:YAGNIの記事への直接リンクを追加しました

于 2010-09-01T13:26:19.963 に答える
14

まずは安定性を重視。アプリケーションの周囲にある種の安定した環境を配置するまで、拡張またはリファクタリングを行うことはできません。

いくつかの考え:

  1. リビジョン管理。Subversion をセットアップすることから始めました。データベース スキーマ、ストアド プロシージャ、スクリプト、サードパーティ コンポーネントなどもリビジョン管理されていることを確認してください。バージョンのラベル付けシステムを用意し、バージョンにラベルを付けて、将来古いバージョンに正確にアクセスできるようにします。
  2. ビルドしてリリースします。開発マシン以外のマシンで安定したリリースをビルドする方法を用意してください。ant/nant、make、msbuild、またはバッチ ファイルやシェル スクリプトを使用することもできます。存在しない場合は、展開スクリプト/インストーラーも必要になる場合があります。
  3. テストの下で取得します。変更によってアプリが破損したかどうかを確認する方法が見つかるまで、アプリを変更しないでください。このためには、テストが必要です。いくつかの単純なスタンドアロン クラスの xunit 単体テストを作成できることを願っていますが、アプリケーション全体を実行するシステム/統合テストをいくつか作成してみてください。高いコード カバレッジがなければ (最初から始める必要はありません)、統合テストが最善の策です。できるだけ頻繁にテストを実行する習慣を身につけてください。それらを拡張するあらゆる機会を利用してください。
  4. 焦点を絞った小さな変更を加えます。アプリケーション内のシステム/サブシステムを特定し、それらの間の境界を改善するようにしてください。これにより、変更による連鎖反応が軽減されます。コードを再フォーマットしたり、最新のファッショナブルなデザイン パターンを適用したりして、コードを「きれいに」しようとする誘惑に注意してください。このようなシステムの好転には時間がかかります
  5. ドキュメンテーション。必要ですが、あまり気にしないでください。私の経験では、システムのドキュメントはめったに使用されません。通常、優れたテストは優れたドキュメントよりも優れています。アプリケーションとそれが実行されるシステム コンテキスト (入力、出力、ファイル構造、データベース スキーマなど) の間のインターフェイスを文書化することに集中します。
  6. 期待を管理します。状態が悪い場合は、おそらく変更を加えようとする努力に抵抗し、タイムスケールを見積もるのが通常よりも難しくなる可能性があります. 経営陣と利害関係者がそれを理解していることを確認してください。

なんとしてでも、すべてを書き直したいという誘惑に注意してください。この状況で正しいことを行うことはほとんどありません。それが機能する場合は、機能を維持することに集中してください。

ジュニア開発者として、助けを求めることを恐れないでください。他の人が言っているように、レガシー コードを効果的に使用することは、Martin Fowler のRefactoringと同様に、読むのに適した本です。

幸運を!

于 2010-09-01T14:10:23.770 に答える
8

あなたの問題#7は断然最も重要です。システムがどのように動作するかわからない限り、すべての技術的な考慮事項は二次的なものです。誰もが単体テストを提案していますが、必要な動作と不要な動作を区別できない場合、どのようにして有用なテストを作成できますか?

したがって、コードに触れる前に、ユーザーの観点からシステムを理解する必要があります。ユーザーと話し、システムを使用してユーザーを観察し、ユースケースレベルでドキュメントを作成します。

はい、コードを1行も変更せずに、数日、場合によっては数週間を費やすことを真剣に提案しています。今のところ、あなたが行った変更は、あなたが気付かないうちに物事を壊す可能性が高いからです。

アプリを理解すると、少なくともテストするのに重要な機能(手動または自動)がわかります。

于 2010-09-01T13:39:20.537 に答える
6

最初にいくつかの単体テストを作成し、それらが合格することを確認します。次に、リファクタリングの変更を行うたびに、テストが合格し続けることを確認し続けます。そうすれば、外部世界に対するアプリケーションの動作が変わっていないことを確信できます。

これには、テストが常にそこにあるという追加の利点もあります。そのため、将来の変更に対してはテストに合格し、新しい変更での回帰を防ぐことができます。

于 2010-09-01T13:14:20.943 に答える
3

何よりもまず、ソース管理システムがインストールされていること、およびすべてのソース コードがバージョン管理され、ビルド可能であることを確認してください。

次に、システムのコア部分の単体テストを作成してみます。そこから、多かれ少なかれしっかりした回帰テストの本体ができたら、実際にリファクタリングを進めることができます。

乱雑なコードベースに遭遇したとき、私は通常、最初の意図をよりよく反映するために、不適切な名前の型とメソッドの名前を変更することから始めます。次に、巨大なメソッドを小さなメソッドに分割してみてください。

于 2010-09-01T13:16:27.567 に答える
2

このレガシーシステムは、すべてスパゲッティコードで、現在機能していることに注意してください。見た目が良くないからといって、物事を変えてはいけません。古いコードを左右中央からリッピングする前に、安定性、新機能、親しみやすさに重点を置いてください。

于 2010-09-01T13:23:12.717 に答える
1

まず、レガシーコードを効果的に使用することは、互いに1分以内に3つの答えから判断すると、おそらく読むのに非常に良い本だと言わせてください。

  1. 悪いデータベーステーブルの設計

これ、あなたはおそらく立ち往生しています。既存のデータベース設計を変更しようとすると、おそらくシステム全体を再設計し、既存のデータの移行ツールを作成することに専念していることになります。よく放っておいてください。

于 2010-09-01T13:27:40.430 に答える
1

他の人が指摘しているように、単にきれいにするためだけに機能するものを変更しないでください。エラーが発生するリスクは大きいです。

私の哲学は次のとおりです。新しい要件を満たすため、または報告されたバグを修正するために変更を加える必要があるため、変更が必要なコードを少しきれいにしようとします。いずれにせよ、変更されたコードをテストする必要があるため、今こそ、少額の追加費用でクリーンアップを行う良い機会です。

根本的な設計変更は最も困難であり、とにかく変更されたすべてのコードをテストするのに十分な大きさの変更を行う必要がある場合に備えて保存する必要があります。

不適切に設計されたテーブルは多くのプログラムで使用される可能性が高いため、不適切なデータベース設計を変更することは最も困難です。データベースに変更を加えるには、データベースを読み書きするすべてのプログラムを変更する必要があります。これを達成する最善の方法は、通常、データベースの特定の部分にアクセスする場所の数を減らすことです。簡単な例を挙げると、顧客レコードを読み込んで顧客口座残高を計算する場所が 20 あるとします。これを、データベースを読み取って合計を返す 1 つの関数と、その関数への 20 回の呼び出しに置き換えます。これで、顧客レコードのスキーマを変更できるようになりました。変更するコードは 20 個ではなく 1 個だけです。原則は単純ですが、実際には、特定のレコードにアクセスするすべての関数が同じことを行うことはほとんどありません。

于 2010-09-01T17:15:50.543 に答える
1

この質問に対する私の標準的な答えは次のとおりです。この場合、私は 10,000 行のクラスの 1 つを取り、スプラウト クラスへの機会を探す傾向がありますが、それは私の傾向にすぎません。最初に他のものを変更する方が快適かもしれません (ソース管理の設定は、優れた最初のステップでした!) できることをテストします。テストできないものをリファクタリングし、一度に一歩を踏み出し、より良いものにします。

進歩するにつれて、どれだけ優れたものを作っているかを覚えておいてください。物事がまだどれほど悪いかだけに集中すると、落胆する可能性があります。

于 2010-09-01T16:03:49.590 に答える
0

設計上の問題を見つけるのは非常に困難です。最初に開始するのは、アプリケーションの設計を理解することです。UMLまたはプロセスフロー図のいずれかを使用して図を作成すると便利です。設計を伝達し、アプリケーションで機能するものであれば何でも機能します。

そこから私はより詳細に行き、「私はそれをこのようにしただろうか」、他にどのような選択肢があるかを自問します。コード債務、つまり、いつものように悪い選択をすることから得られる債務は簡単にわかりますが、予算、時間、リソースの可用性など、他の要因が関係している場合もあります。動作しているが設計が悪いアプリケーションをリファクタリングする価値があります。

今後の新機能、変更、バグ修正などが多数ある場合は、リファクタリングするのが良いと思いますが、アプリケーションがめったに変更されず、安定している場合は、そのままにしておく方がよいでしょう。

注意すべきもう1つの側面は、コードがサービスまたはモジュールとして別のアプリケーションによって使用される場合、リファクタリングは、明確に定義され、それを証明するための単体テストが行​​われると、最初にインターフェイスとしてサーバーとなるコードの周りにスタブを作成することを意味する場合があります仕事。詳細を入力するテクノロジーを選択できます。

于 2010-09-01T13:24:32.183 に答える
0

レガシーコードを効果的に使用すると役立つ場合があります。

于 2010-09-01T13:18:39.000 に答える
0

この主題に関する優れた本は、Michael Feathers 著の Working Effectively with Legacy Code (2004) です。大きなクリーンアップに向けて作業しながら、小さな変更を加えるプロセスを経ます。

  1. 単体テストを作成し、重複するコードを見つけて削除します。
  2. 単体テストを作成し、長いメソッドを一連の短いメソッドに分割します。
  3. 単体テストを作成し、重複するメソッドを見つけて削除します。
  4. 単一責任の原則に従うように、単体テストと分割クラスを記述します。
于 2010-09-01T13:17:30.420 に答える
0

最初に、コード内でいくつかのアクションをトリガーできる単体テストをいくつか作成してみてください。

すべてを SVN にコミットし、それにタグを付けます (何か問題が発生した場合に備えて、エスケープ ポッドを用意します)。

inCode Eclipse プラグインhttp://www.intooitus.com/inCode.htmlを使用して、提案されているリファクタリングを探します。提案されたリファクタリングが問題に適しているかどうかを確認してください。それらを理解するようにしてください。

前に作成したユニットで再テストします。

FindBugs や PMD を使用して、その他の微妙な問題をチェックできるようになりました。

すべて問題なければ、再度チェックインすることをお勧めします。

また、パターンを適用できるいくつかのケースを検出するために、ソースを読んでみます。

于 2010-09-06T17:57:20.420 に答える