6

私はレガシー Java システムの保守とリファクタリングを任されています。Java はよく知っていますが、現在は C# と .NET を使用しています。

レガシー システムは、クライアント/サーバー アーキテクチャである RMI を使用し、1.4 JVM 用に設計されています。UI(私が知る限り)、Swing、およびAWTに使用しています。

私の質問は次のとおりです: 渡されたばかりのコードベースを理解するための最良の方法は何ですか? 画面のフローチャート、RMI 呼び出し間の境界の定義、単体テストの作成 (テスト可能な部分) を考えています。

なじみのないコードベースを渡されたとき、あなたはどうしますか?

ありがとう!

-ジャロッド

4

10 に答える 10

5

受け取った新しいコードに対して最初に行うことは、既存の単体テストを確認することです。通常、新しいテストを作成することは 2 番目の作業です。

于 2009-02-09T00:37:40.670 に答える
4

それはコードベースの品質に大きく依存します。実際には、それをさらに狭く定義することができます-それはコードがどれほど明確で、どれだけコメントされているかに依存します(そして私はこれを、文書化されていないレガシーコードベースを繰り返し継承する立場にある人として書いています)。

コードベースが悪いほど、外部からその機能を推測する必要があります-関数が何をしているのか理解できない場合は、少なくともGUIが何を意味しているのかを理解できる可能性がありますそれがやっている。RMIインターフェースを持つことは、GUIが見る必要のあるものの単純化された図を提供するという点で、祝福かもしれません-リモートインターフェースから抽象化することは非常に良い考えです。

コードベースが本当に貧弱な場合、適切に実装されていても間違っているものをテストしている可能性があるため、単体テストは役に立たない可能性があります。私が最後に受け継いだものからの例:(名前と説明は意図的に削除されました-いずれの場合も元の名前では役に立ちませんでした)

 public static int[] a (List<int[]> input){  

   ... lots of opaque rubbish
   return b(input);
 }

 public static List<int[]> b{ List<int[]> input)
 {
   ... more crap....
   return some horribly mangled list of int[];
 }

結局のところ達成されたのは、2番目の要素の値で配列を並べ替えることでした。この場合、 bが適切に動作するかどうかをテストしても意味がありません。

正気を保つための提案:

  • 明らかに使用されていないコードを削除します。
  • 「マジックナンバー」を除外してみてください
  • ハードコードファイル、パス、またはリソース参照を見つけて、それらをプロパティ、またはそれらを処理するための他の中央の一般的な方法に分解します。
  • アプリが実際に想定どおりに動作しているかどうかを確認してください。ユーザーが「実際には正しく機能しなかった」と感じたものを実際に表現することができない、非常に複雑な機能も珍しくありません。
  • モノが最初に設計されたときからのオリジナルのドキュメントや仕様を見つけてください。
  • 1.4について言及しているので、マップを一般化すると、渡されるオブジェクトの種類を明確にすることができます。HashMapに裏打ちされたオブジェクトがあり、そのオブジェクトがどのように読み込まれるかが謎である場合、それが実際に文字列から整数へのマップであると判断することで、実際に生活を簡素化できます。これは、実際に想定されているものよりもはるかに簡単に理解できることがよくあります。やっている。

もちろん、コードベースが適切に記述されている場合、これのほとんどは不要ですが、いずれの場合でも、作業ははるかに簡単になります。そして成功を祈る。

于 2009-02-09T01:06:22.363 に答える
1

新しいコードを受け取ったときに最初にすることは、「それを機能させるようにする」ことです。これはつまり:

  • 最初にインストールします(インストールノートがある場合はそれに従って)

  • 次に、それに慣れます(ユーザーマニュアルを読み、いくつかの重要なユースケースを実行することによって)

  • 次に、いくつかのリバースエンジニアリングを行ってメインレイヤーを見つけます。クラスと依存関係

  • 次に、新しいテストケースを作成することを考えることができます(最初に受け入れレベルで、後で回帰テストに役立ちます)

  • 次に、この機能を追加すること(必須でない場合でも)または既存の機能のパフォーマンスを向上させることについて、いくつかの「課題」を自分自身に与えます。これは、既存のコードベースを掘り下げるための良い方法です。

  • もちろん、既知の保留中のバグ/ RFEがある場合は、最初にこれらに取り組みます

特定のケースでは、RMI呼び出し、どの呼び出しまたは呼び出しのシーケンスを文書化して、可能な場合はそれを使用レベルの機能に関連付けようとします。

さらに(実際にはそれが最初に来るはずです)、知っておくべき重要なことの1つは、このシステムの主な目的です(なぜ、顧客はこのシステムを使用するのですか?)。目標を理解し、それらを念頭に置くことで、コードを維持しながらこれらの目標から離れることを回避できます。

于 2009-02-09T01:08:02.937 に答える
1

私が出席した Mike Hill の講演では、悪いレガシー コードを処理するために使用するプロセスについて話しました。彼はそれを「マイクロテスト」と呼びました。基本的には、テストしたいものをそれぞれ (独自の関数または小さなオブジェクトで) 分離し、その周りにテストを記述します。これらのテストは、ビジネス上の意味で物事を主張することを意味するものではありません。テスト対象の行が実行された後のシステムの状態をキャプチャすることを目的としています。通常、彼は変数がデバッガーで持っていた値を持っていると断言します。当然のことながら、これらのテストは最初は成功しますが、十分な数のテストを作成すると、システムのスナップショットを効果的に取得できます。

これらのテストが実施されると、彼はそのコードのリファクタリングを開始して、それが何をしようとしているのかを理解しようとしました。関数 (またはオブジェクト) の動作を少しでも変更すると、「マイクロテスト」が失敗するため、安全に実行できました。つまり、大きな設計変更を行うことはできませんでしたが、多くのノイズを除去し、システムが何をしているかを把握することができました。コードが何を達成しているのかについて明確な考えが得られると、彼はそれを改善したり、バグを見つけたりすることができました.

これに関する無料のリソースはあまりないため、リンクを提供していません。うまくいけば、私はあなたにいくつかのアイデアを与えるのに十分な説明をすることができました.

于 2009-02-09T04:46:32.257 に答える
1

経験から、レガシー システムを学習する際には 3 つの主要な目標があることがわかりました。

  • コードが何をすべきかを学ぶ
  • それがどのようにそれらを行うかを学びます
  • (重要なことに)なぜそのようにするのかを学ぶ

これらの 3 つの部分はすべて非常に重要であり、開始するのに役立ついくつかのトリックがあります。

まず、すべてを理解するためにコードを ctrl キーを押しながらクリック (または IDE で使用するもの) する誘惑に抵抗してください。おそらく、この方法ですべてを大局的に把握することはできません。特に、各行が、それが何であるかを理解するために他の複数のクラスを見る必要がある場合はなおさらです。

可能であればドキュメントを読んでください。それは通常、その後のすべてを構築するための精神的な枠組みをすばやく得るのに役立ちます。

可能な場合はテスト ケースを実行します。

質問がある場合は、知っている人に尋ねることを恐れないでください。確かに、無意味なクエリで他の従業員の時間を無駄にするべきではありませんが、単に理解できないことがある場合 (これは、「これをa ___" か何か)、何かを台無しにして理由がわからない前に、答えを見つける価値があるでしょう。

最終的にコードを読み始めたら、論理的な「メイン」の場所から始めて、そこから進んでください。コードを上から下、またはアルファベット順などで読むだけではいけません (これはおそらく明らかです)。

于 2009-02-09T05:12:31.913 に答える
0

ビルドして実行することが私の最初のことです。対処しようとしていた問題を理解し始めます。

たぶん、それをJUDEのようなUMLツールにインポートして、クラスがどのように相互作用するかを把握することができます。

JUnitテストを書くことは素晴らしい提案です。アプリがどのように階層化されているかを確認したいと思います。テストが難しい場合は、結合しすぎている可能性があります。ユニットテストはそれを教えてくれます。また、リファクタリングが適切であると判断した場合は、セーフティネットが提供されます。

JDK 1.4?それはそのサポート寿命の終わりを過ぎています。また、コードが少なくともJDK 5、できればJDK 6でビルドおよび実行されるかどうかも確認したいと思います。おそらく、これらのJUnitテストのいくつかをJMeterにスラップして、5人の同時ユーザーで簡単な貧乏人の負荷テストを実行できます。

データモデルがある場合は、それをERWinに取り込み、テーブル、オブジェクト、および画面がどのように一緒に流れるかを確認し始めます。

于 2009-02-09T01:28:16.977 に答える
0

もちろん、ステップスルーを試すこともできます。遅いですが、コードのウォークスルーに1日費やすと、後でバグ検索を1週間節約できる可能性があります...

また、スカベンジャーハントアプローチを試して、すべての機能のリストを作成し、そのコードをハントすることもできます...

于 2009-02-09T03:16:13.410 に答える
0

最初にコードをざっと見て、その構造を理解します。次に、アプリをデバッグ モードで実行し、数回実行します。これにより、流れと構造が表示されます。

Netbeans を使用して、クラス図をリバース エンジニアリングします。

于 2009-02-09T03:53:32.760 に答える
0

RMI を使用した Java 1.4 はレガシーではありません。これは、一部の標準では実質的に新しいものです。

単体テスト、コード/呼び出しのトレース、UML ダイアグラムの作成など、物事がどこにあるかを理解するためにできることは何でもしてください。

より小さなセクションから始めて、コード パスをたどって状況を把握するか、コードを確認する必要があるいくつかの小さな修正/改善を自分に割り当ててみてください。

于 2009-02-09T00:46:53.003 に答える