web-dev-qa-db-ja.com

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

そのコードベースを維持する契約を結ぶ前段階として、かなりのレガシーコードベースのように見えるものを評価するように求められました。

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

内側から見たサイト構造は混乱しています。 「_OLD」と「_DELETE」というサフィックスが付いたフォルダがいたるところにあります。フォルダの多くは、目的を果たさないように見えるか、非常に不可解な名前を持っています。正規のように見えるフォルダ内であっても、未使用の古いスクリプトがいくつも存在する可能性があります。それだけでなく、他の方法で操作できるスクリプトでも、間違いなく多くの機能しないコードセクションがあります(差し迫った問題ではありません)。

これは、現メンテナからサイトの元の開発者/メンテナへの引き継ぎです。これらの種類のシナリオでは当然のことながら典型的であるが、現職者は、新しく選出されたメンテナにプッシュするために契約上および法的に必要とされること以外は、引き継ぎとは何の関係も望んでいない。したがって、既存のサイト構造に関する情報を既存のサイトから抽出することは、問題外です。

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

ですから、保守性のためにコードベース全体を評価する方法について誰かがより良い提案をしているのではないかと思います。 (私がアクセスできる)WebサーバーのOS上のファイルへのアクセス頻度のグラフを見る方法があればすばらしいでしょう。これはどのファイルが最も重要であるかについての洞察を提供するかもしれません。使用されないファイルを削除できる(一部のファイルは1年に1回しか使用できないため)。

21
Engineer

あなたがするように求められているのはyourクライアントに適切な提案をotherクライアント(owner-of-the-nightmare-code)に書き込むための入力を提供することなのでそのコードでの作業については、私はすぐに出かけて、徹底的なテストやリファクタリングなど、この時点でこれらの行に沿ったものは何もしないと言います。おおまかな見積もりを取得するための時間が非常に短い可能性があります。私の答えは同じ状況での私の経験に基づいているので、私の解釈が正しくない場合は、以下のすべてを無視してください。

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

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

32
jcmeloni

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

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

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

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

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

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

4
Kyle Hodgson

典型的なJavaコードベースでは、PMD、FindBugs、Sonarなどのツールの使用を検討してから、ツールのレポート(デッドコード、ドキュメント化されていないコード、重複したコード、等。)

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

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

2

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

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

1
Ryathal

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

1
Mike Baranczak

注:コード自体の使用方法についてお聞きしましたが、データベースの使用方法を強調しました。答えは、私が述べたすべての点で両方のケースに適用されます。

前の段落で、独自の質問の一部にすでに回答しました。アプリケーションの実行中にアクセスされるものを確認します。

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

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

  3. 静的分析と一部のコンパイラもデッドコードを明らかにするかもしれませんが、それでもあなたが望む答えを与えません。

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

これらの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%以上影響を与えるとは思いませんなので、その部分については気にしません。

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

また、自分自身を保護するために、事前に決められた料金でこのプロジェクトに費やす月あたりの時間数を制限することも検討してください。

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

0
Sarel Botha