レガシーコードベースで、使用されているものと使用されていないものをすばやく見つけるにはどうすればよいですか?


21

そのコードベースを維持する契約を結ぶ前に、実質的なレガシーコードベースのように見えるものを評価するように頼まれました。

このような状況になったのはこれが初めてではありません。現在の例では、コードは適度に知名度が高く、かなり高負荷のマルチプレイヤーゲームサイト用であり、一度に少なくとも数千人のプレイヤーをオンラインでサポートします。そのようなサイトの多くはそうであるように、これはフロントエンドとバックエンドのテクノロジーが混在しています。

内側から見たサイト構造は混乱しています。「_OLD」と「_DELETE」という接尾辞が付いたフォルダがいたるところにあります。フォルダの多くは、目的を果たさないか、非常にわかりにくい名前を持っているようです。正規のフォルダ内にさえ、いくつもの古い未使用のスクリプトが存在する可能性があります。それだけでなく、それ以外の場合は操作可能なスクリプトであっても、間違いなく多くの無効なコードセクションがあります(はるかに差し迫った懸念)。

これは、現在のメンテナーからサイトの元の開発者/メンテナーへの引き渡しです。これらの種類のシナリオでは当然のことですが、現職者は、契約上および法律上、新たに選出されたメンテナーにそれをプッシュするために必要なもの以外、ハンドオーバーとは何の関係もありません。したがって、既存のサイト構造に関する情報を現職から抽出することは、単に問題外です。

コードベースに入るために頭に浮かぶ唯一のアプローチは、サイトのルートから始めて、リンクされたスクリプトをゆっくりと、しかし確実にナビゲートすることです...そしておそらく何百もの使用があり、そうでないものは何百もあります。特に古いFlashアプリケーションでは、他のスクリプトへのリンクがテキストファイル(.AS / ActionScript)ではなくバイナリ(.FLA)に埋め込まれている可能性があるため、サイトの大部分がFlashにあることを考えると、これはさらに簡単ではありません。

だから、保守性のために全体としてコードベースを評価する方法について誰かがより良い提案を持っているのだろうかと思っています。WebサーバーのOS(アクセスできる)上のファイルへのアクセス頻度のグラフを表示する方法があれば素晴らしいと思います。一度も使用されないファイルがあるため、一度も使用されていないファイルを削除できます。


7
フラッシュについては十分に知りませんが、コードが存在しないときにコンパイルエラーが発生した場合は、参照されているかどうかを確認するためにフォルダーの名前を変更できる必要があります。
Oded

邪悪な解決策:それらを削除して、エラー/バグレポートを待ちます。(回復可能であることを確認してください!)
イズカタ

1
@Nick入札する必要がある/そうでなければ取得する必要がある契約の次のフェーズの一部として評価の支払いを受けているかどうかを明確にできますか?あなたの答えは「ツールはありますか?」という質問を変えることはありませんが、私たちの中にはあなたの状況により適したプロセスを作り上げることができます。
jcmeloni

@jcmeloniいいえ、私は評価のために支払われていません。しかし、私の経験では、そしてここ数日で私が拾った小さなものから、彼らは現在テーブルに他に誰もいません。私のスキルセットはかなり珍しいので、引用に基づいて、他の誰もそれを競っていないという安心感があります。問題の実際の見積もりは、私のクライアントになる予定のクライアントからのものであり、クライアントは契約の再授与を計画しています。本当に私の終わりから、私は彼らが上記の引用を提供するのを支援するつもりです。HTH。
エンジニア

@Oded Renameは、試行錯誤の削除よりも間違いなく簡単です!そこに良い思考。これはもう1つのツールです。
エンジニア

回答:


32

あなたがするように求められているのは、そのコードの作業のために他のクライアント(悪夢の所有者)に適切な提案を書くためクライアントに入力を提供することですので、私は外に行きますこの時点では、徹底的なテストやリファクタリングなどの行に沿って何かを行うつもりはないと言います。おおよその見積もりを得るのに、おそらく非常に短い時間です。私の答えは同じ状況での私の経験に基づいているため、私の解釈が間違っている場合は、その後のすべてを無視してください。

  • スパイダーツールを使用して、そこにあるページとインバウンドの内容を把握します。この点に関しては、特定の「監査目的のスパイダー」ツールではなく、基本的なリンクチェッカーツールでさえ役立ちます。
  • 基本的な監査/在庫スプレッドシートを作成します。これは、ファイルのリストとそれらの最終変更時刻をディレクトリごとに整理するのと同じくらい簡単です。これは、スコープの感覚をつかむのに役立ちます。_OLDや_DELETEのようなディレクトリにアクセスすると、a)評価がそれらのディレクトリにないものに基づいていることに気付くことができます。b)それらのディレクトリの存在と可能性悪意のある/隠された悪夢は、何らかの方法でクライアントの入札で考慮されるべきより深い問題を証明します。_OLDまたは_DELETEで起こりうる問題を列挙するのに膨大な年を費やす必要はありません。情報は最終的な入札に反映されます。
  • 完全にWebベースのアプリのように聞こえる内容をレビューしていることを考えると、標準のログアナライザーツールでさえあなたの友達になります。スプレッドシートに「これはアクセスされたスクリプトのトップ10に含まれている」などの感覚を追加できます。スクリプトがFlashファイルに埋め込まれているため、スパイダー可能でない場合でも、POSTまたはGETを介してアクセスされ、サーバーログに表示される可能性が高くなります。100個ではなく10個(またはその逆)のアクセス頻度の高いスクリプトが10個あることがわかっている場合は、メンテナンス作業がどのように行われるかを知ることができます。

複雑なサイトでも、上記で説明したことは、1日または1日半でできることです。あなたに与えるつもり答えているので、あなたのクライアントは、この「のようなものがここにお尻で驚異的な痛みになるだろう、とされている、あなたがそれに応じて入札しなければならないので、あなただけの豚に口紅を置くことになりますいくつかの理由です「または「合理的な人なら誰でも維持するのではなく、最初からやり直すために入札するので、それに応じて入札する必要があります」または「これはそれほど悪くはありませんが、特定の時間枠で一貫した仕事の流れになるので、それに応じて入札してください」 、ポイントは彼らが入札をするつもりであり、したがってあなたが完全なコンテンツとアーキテクチャ監査を行うために直接雇われていた場合ほど正確である必要はないということです。


2
+1これは素晴らしい答えです。+5ボタンはどこにありますか?
エンジニア

1
TL; DR:必要になるまで、うさぎの穴に落ちないでください。:)
jcmeloni

4

レガシーコードを効果的に使用する」という本に記載されているパターンを使用して、既存のソースコードを(書き換えではなく)リファクタリングすることを強くお勧めします。

この本では、ユニットテストでレガシーコードを効率的にカバーするためのいくつかのメカニズムを詳しく説明しているため、コードの安全なリファクタリングを開始できます。この本は、アプローチの背後にある哲学を説明する部分と、「変更を行うには永遠に時間がかかる」、「あまり時間がないので変更する必要がある」などの特定の問題を解決するいくつかの章に分かれています。 、および「このクラスをテストハーネスに入れることができません」。これらの各章には、テストのベストプラクティスを実際の問題に適用する方法を学習するのに役立つ詳細かつ実証済みのテクニックがあります。

この本を読むと、「私たちは一人ではない」という非常に現実的な感覚を残しました...私たちの多く、あるいはおそらく私たち全員が、管理が困難になった複雑なコードベースを扱っています。本にリストされている技術は私に多くの希望を与えてくれました、そして私は個人的にほとんどすぐにそれらを適用することができました。

Joel Spolskyのブログ投稿は、ゼロから始めるのではなく、既存の機能するコードベースを維持するのが最善である理由を説明する素晴らしい仕事をしています。私はそれを要約する記事から引用を選びましたが、素晴らしい読み物です。

「プログラマーが常にコードを捨ててやり直したいという微妙な理由があります。理由は、古いコードは混乱だと思うからです。そして、興味深い観察結果があります。おそらく間違っている。古いと思う理由コードが混乱しているのは、プログラミングの基本的な法則によるものです。

コードを書くよりもコードを読む方が難しいです。」-http://www.joelonsoftware.com/articles/fog0000000069.html


4
+1。ジョエルのコメントに応えて、「それは血まみれではないはずです。」私は問題を固有のものとは思わないからです。多くの人は見苦しいコードを書いて気にしないという事実の一部であると考えていますが、他の多くの人はかなり良いコードを書いていますが、「自己文書化コード」の概念で生きています...単なるBSです:自分のコーディングスタイルはすべてプライバシーで望みますが、パブリックコードベースに関しては明日がないようにコメントを生成するだけです。痛くない。そして最後に、限られた時間の予算で、レガシーコードベースで作業を行わなければならない人々がいます。
エンジニア

2

典型的なJavaコードベースでは、PMD、FindBugs、Sonarなどのツールの使用を検討し、レポートツール(デッドコード、文書化されていないコード、重複したコードなど)を理解しようとします。

レポートに基づいて、アプリケーション/サイトのさまざまなレイヤー(ビジネスレイヤー、DB、SQLなど)を見つけようとします。

レイヤーが結合されている場合(サーブレット内のhtml、Javaコード内のsql)これらの各ステップは分離されていると見なされるべきであり、各ステップの最後にコミットできます(ブランチを開始してからマージする) 。


1
ありがとう。あなたの答えはややJava特有ですが、階層化されたアプローチを見るのは興味深いです... 考えること。
エンジニア

1

あなたの説明から、このコードは維持不可能な状態になっているようです。つまり、最善のアプローチは完全な書き直しです。乱雑なコードベースを維持可能な状態に保つために機能する高品質のツールがあれば、開発者ははるかに小さな給料を受け取ることになります。フォルダーから古い不要なコードを調べてクリーンアップすることは可能ですが、それは手動のタスクであり、不合理な時間をかけずにすべてを取得することはできないでしょう。私はここで推測していますが、作業中のコード自体はファイル構造と同じくらい混乱していることを意味します。何かを更新または修正します。

既存のコードを維持可能な状態にするために必要な労力は、書き直しをやり直す労力と同等以上になることを強調します。何かを維持することの一部は、「小屋の後ろでそれを取り、それを撃つ」ときを知ることです。


通常、私はトスアンドリライトアプローチで100%あなたと一緒にいます。しかし、この場合(少なくとも今のところ)、数週間かかるより大規模なオーバーホールではなく、サイトを維持するための作業に対してのみ報酬が支払われます。また、今すぐにしたい場合でも、それを行うことや、外出先で持っている他の契約を押さえることができませんでした。これは、週ごとの可用性が明確に制限されているためです。週に最低40時間。
エンジニア

1
トスに反対し、書き直してください!from joelonsoftware.com/articles/fog0000000069.html ...「プログラマーは常にコードを捨ててやり直したいという微妙な理由があります。その理由は、古いコードは混乱だと思うからです。そして、興味深い観察結果があります。 :おそらく間違っています。古いコードが混乱していると考える理由は、プログラミングの基本的な法則によるものです。コードを書くよりもコードを読む方が難しいのです。」代わりに、私は強くお勧めしますリファクタリング:amazon.ca/Working-Effectively-Legacy-Michael-Feathers/dp/...
カイルホジソン

1
@KyleHodgsonは、実際にはコードが混乱している場合があります。コードを読む前にコードを見つけるのが面倒な場合は、最初からやり直します。
リャサル

ええ、それはそれほど明確ではないと思いますが、その本は読む価値があります。コードベースのサイズ/複雑さ、および作業を行うために利用可能なウォームボディに大きく依存します。
エンジニア

1

Webクローラーは、アクセス可能なURLを判別するのに役立ちます。特に、FlashまたはJavaScriptからリンクを抽出するのに十分賢い場合。Webページのリストを取得したら、それらを調べて、参照するファイルをリストします。このプロセスの後に残ったものはすべて、デッドコードと見なされる必要があります。


1
あなたの最後の文に強く反対します。クローラーは、単一または複数の開始点を持つ有向グラフとしてリンクされているページのみを見つけることができます。しかし、私たちがウェブサイトについて話すとき、他のページにリンクする「リンク先ページ」と呼ばれるものもありますが、それらを指すリンクはありません。また、管理インターフェイスの古い部分が他のページから切断されている場合もあります。現在、このタイプのプロジェクトがあります。
scriptin

0

注:コードの使用法について質問されている間、データベースの使用法にアクセントを付けました。答えは、私が言及したすべての点で両方の場合に適用されます。

あなたはすでに最後の段落であなた自身の質問に部分的に答えました:アプリケーションの実行中にアクセスされるものを見てください。

  1. データベースのプロファイル作成し、プロファイラーに1日間のすべてのクエリを記録するように依頼できます。最も使用されているデータベースオブジェクトの概要は表示されますが、どのオブジェクトが使用されていないかはわかりません。また、結果に注意する必要があります。たとえば、テーブルはストアドプロシージャでのみ使用できますが、プロファイラからのクエリを見ると、テーブルがまったく使用されていないように見えます。

  2. ソースコードを確認し、クエリを検索する方が便利です。すべてのクエリを収集した後は、頻度(プロファイラが便利)ではなく、使用/非使用の観点からデータベースの使用状況を十分に理解できます。使用済みテーブル。悲しいことに、長年のコードベースで不適切に書かれている/維持されていないため、特にクエリが動的に構築される場合、非常に困難でエラーが発生しやすくなる可能性がありますselectテーブルの名前としてパラメータを使用するメソッドを想像してください。おそらくソースコードを見ることで、パラメーターの可能な値が何かを知っていますか?)。

  3. 静的解析と一部のコンパイラはデッドコードを明らかにすることもありますが、それでも必要な答えが得られません。

  4. データ自体またはデータベースメタデータの分析により、興味深い情報が明らかになる場合があります。たとえば、テーブルがあることは容易主張することになりLogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...)、それは10の000年の2009年から2006年のための一日あたりのレコード、9月からレコードなし、18含まれている場合は、もはや使用されていない目を、2009年と同じではAの真実ではありませんほとんど読み取り専用になるようにインデントされたデータを含むテーブル。

これらの4つのポイントを合わせると、使用済みテーブルのリストが表示されます。残りのものは使用されるかされません。アサーションを作成してテストすることもできますが、適切な単体テストのカバレッジがなければ、簡単ではありません。「簡単な」方法も失敗します。たとえば、products_delme_not_usedテーブルがある場合、そのテーブルがまったく使用されていないことをアサートし、コードで「products_delme_not_used」を確認できます。これは楽観的です。古いコードベースで次のようなDailyWTF候補を見つけることは珍しいことではありません。

// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this `if` block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}

このコードが実際にproducts_delme_not_usedテーブルを使用していることがわかりますか?

もし私があなただったら、私は:

  1. すべてのデータベースオブジェクトを所定の場所に保持し、
  2. アプリケーション全体をリファクタリングします(価値がある場合)。
  3. (リファクタリング中に)アプリケーション、特にデータベースの使用状況を文書化します。

最後の2つの手順を完了すると、おそらくデータベースの使用法をよりよく理解できるようになります。これは、使用されなくなったテーブルの名前を把握するのに役立ち、多かれ少なかれ安全に削除できます。


0

見積もりを作成するのに十分な情報を取得する必要があるので、その努力に集中するように思えます。

このサイトに関連するユースケースの数を判断しようと思います。通常、これにより、サイトがどれほど大きく複雑であるか、およびサイト/アプリケーションを再作成または維持するのにどれだけ時間がかかるかがわかります。

はい、時にはコードが使用されないことがあり、アプリケーションが実際よりも少し大きく見えることは事実ですが、これがせいぜい20%以上しか数値に影響を与えないと思います、その部分については心配しません。

ソースコードを見ると、Webページとデータベーステーブルがこの発見に役立ちます。

また、あなた自身を守るために、事前に決められた料金でこのプロジェクトに費やす月あたりの時間数を制限することを検討することもできます。

使用されているものと使用されていないものを発見する限り、本当に簡単な方法はありません。コード分​​析ツールは役立つかもしれませんが、このような複雑な問題に対処しているので、役立つ単一のツールは存在しません。特定の領域ごとに、おそらく役立つコード分析ツールを見つけることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.