このトピックでは、レガシーコードの概念と分類について説明し、さまざまなタイプのレガシーコードに対応するための戦略を提供します。さらに、このトピックでは、コーディングアシスタントがレガシーコードの保守をどのようにサポートできるかに焦点を当てています。
レガシーコード
古いテクノロジーに関連するコード:
サポートされなくなったオペレーティングシステムまたはソフトウェアライブラリに関連するコード。
廃止された技術スタックまたはプログラミング言語に依存するコード。
レガシー機能との互換性のために予約されているコード:
最新のソフトウェアの古いバージョンの機能との互換性のために予約されているコードセグメント。
下位互換性のために予約する必要があるコード。
対応するドキュメントがなく、保守されていないコード:
対応するドキュメントがない古いコード。
単体テストやコードレビューなどの最新の開発プラクティスが不足しているコード。
レガシーコードのソリューション
レガシーコードの問題に対処するには、次のいずれかの戦略を使用できます。
戦略 | 長所と短所 |
コードの書き換え | コストが高く、既存のシステムは期待どおりに動作し続ける可能性があり、コードのリスクにつながります。 |
コードのリファクタリング | |
単体テストの補足 | 単体テストは、コードの問題を特定し、コード変更の可能性に対する品質保証を提供するために使用されます。 |
上記の表は、単体テストの補足がレガシーコードの問題を解決するための効果的な方法であることを示しています。ただし、この方法には依然として次の課題が存在します。
大量のレガシーコードには単体テストがなく、コード間の複雑な依存関係によりテストコストが非常に高くなります。
適切な単体テストを定義するための具体的なメトリックが明確ではありません。
単体テストが必要なコードが明確に特定されていません。
単体テストのよくある間違い
アサーションのない誤った単体テスト: 開発者は、コードカバレッジを向上させるためにアサーションなしで関数を呼び出すことがあり、多くの無効な単体テストが発生します。
ホワイトボックステストと見なされる単体テスト: 一部の見解では、単体テストをホワイトボックステストとして分類しています。ただし、単体テストは実際には関数シグネチャに固有のブラックボックステストです。
実際の環境に依存する単体テスト: 単体テストを妨げる主な要因は、怠惰さと環境依存の構成です。 Stub または Mock を使用して IP アドレスやデータベースなどの外部環境への依存関係を削除しないと、単体テストは FIRST 原則 (高速、独立、反復可能、自己検証、タイムリー) を満たすことができません。
単体テストを選択的に実行する
利点に加えて、単体テストはコストを発生させます。レガシーコードを費用対効果の観点から分析すると、レガシーコードの単体テストを補足できます。これは、単体テストを選択的に実行できることを意味します。コストとメリットをどのように区別しますか?
レガシーコードの単体テストの費用対効果に基づく象限分類
レガシーコードに固有の単体テストは、コストとメリットに基づいて象限に分類できます。次の図は、単体テストの分類基準と象限を示しています。

分類基準
X 軸 (コスト): コードの依存関係が高いほど、テストコストが高くなります。
Y 軸 (メリット): コードの複雑さが高いほど、品質の向上度が高くなります。
4 つの象限
コード分類 | 特性 | 説明 | メリット | コスト |
アルゴリズムコード | 高い循環的複雑度とファンイン | 多くの条件判断とループ文が含まれており、少数のコードに依存していますが、多くのコードから依存されています。 | 高 | 低 |
些細なコード 些細なコード | 低い循環的複雑度と高いファンイン | 単純なロジックを使用し、1 行または 2 行のコードのみが含まれています。 | 低 | 低 |
コーディネーターコード | 低い循環的複雑度と高いファンイン | 呼び出し関係の上位層にあり、他のコードを呼び出すことによって特定のビジネスシナリオを反映します。 | 低 | 高 |
過度に複雑なコード | 高い循環的複雑度とファンイン | 複雑なロジックを使用し、複数の依存関係があり、多くの関数とパラメーターが含まれています。典型的なコードスメルです。 | 高 | 高 |
循環的複雑度と依存関係の理解
循環的複雑度: コード内の論理ブランチの数。
ファンイン: モジュールを直接呼び出す親モジュールの数。ファンインが大きいほど、モジュールの再利用度が高いことを示します。
ファンアウト: モジュールが直接呼び出すモジュールの数。ファンアウトが大きいほど、モジュールが多くのモジュールに依存していることを示します。
さまざまなタイプのコードの戦略
上記の分析に基づいて、次の戦略がレガシーコードに適用されます。
アルゴリズムコードの場合は、単体テストを生成できます。
コーディネーターコードの場合は、API テストを実行できます。
過度に複雑なコードの場合は、コードをリファクタリングする適切な機会を探すことができます。
些細なコードの場合は、コードを処理する必要はありません。

コーディングアシスタントを使用してレガシーコードを処理するコーディングアシスタントレガシーコードを処理する
1. プロジェクトを理解する
プロジェクトのレガシーコードを保守する場合、@workspace 機能を使用して、プロジェクト全体の目的とプロジェクトに含まれるモジュールを理解できます。

2. さまざまなタイプのコードを処理する
アルゴリズムコードの単体テストを生成する
本番コードに基づいてコードを生成するセクションを選択します。生成中に、必要なフレームワークや Mock などの依存関係情報に焦点を当てることができます。単体テストコマンドが生成された後に、関連情報を追加できます。たとえば、/generate unit testingCppUTest です。

一般に、既存のコードから生成される単体テストケースの数は通常限られています。単体テストのテストシナリオとユースケースの数に特定の要件がある場合は、新しく生成された単体テストファイルでテスト関数を継続することで、より多くの単体テストを生成できます。継続中、コーディングアシスタントは既存のユースケースにできるだけ従い、コンテキストの参照として使用します。

コーディネーターコードで API テストを実行する
単体テストはコーディネーターコードの理想的なソリューションではなく、依存関係が多すぎるためテストコストが大幅に増加します。このようなコードでは、API テストまたは機能テストを実行することをお勧めします。ただし、開発者は自動テストケースを作成する際に問題に遭遇することがよくあります。したがって、コーディングアシスタントを使用して、テストフレームワークをすばやく習得し、理解することができます。

ユースケースを作成するには、ユースケースのテスト対象の関数を選択し、Al コーディングアシスタントの会話ウィンドウで直接質問します。たとえば、Robot Framework に基づいて次のコードに対して生成されるテストケースについて、Al コーディングアシスタントに質問できます。このようにして、対応するキーワードを開発できます。
適切なタイミングで過度に複雑なコードをリファクタリングする
過度に複雑なコードの場合は、AI コーディングアシスタントの /generate optimization コマンドを使用して、選択したコードの最適化の提案を取得できます。コードレビューと最適化は、構文の問題、例外の改善、コードのクリーンさ、セキュリティ、リスクなど、複数の側面から最適化の提案を提供します。

複雑なレガシーコードの最適化については、開発者は包括的な最適化とリファクタリングを盲目的に行わないことをお勧めします。レガシーコードの変更は重大なリスクをもたらす可能性があります。したがって、開発者は特定の状況に基づいて適切なタイミングでコードをリファクタリングおよび最適化し、「ボーイスカウトルール」に従う必要があります。このプロセスでは、コーディングアシスタントも強力なサポートを提供します。
まとめ
前述の内容は、レガシーコードを処理する際に参照できるベストプラクティスを提供します。レガシーコードを効果的に処理するには、コードの複雑な構造を深く掘り下げ、考えられるすべてのブランチノードを詳細にトレースする必要があります。このプロセスでは、潜在的な欠陥を特定して修正することに加えて、限られた時間内にすべてのタスクを完了する必要があります。レガシーコードの処理に必要な時間を最小限に抑えるために、開発者はコードの破損を防ぎ、ツールを適切に使用し、初期の記述段階で適切なプログラミング原則に従うことをお勧めします。