ソフトウェアメンテナンスとは、納品後のソフトウェアの修正のことです。
ソフトウェアのメンテナンスは、新規開発に比べてスキルが低く、報酬も低いとよく考えられています。そのため、アウトソーシングやオフショアリングの対象となることがよくあります。通常、ソフトウェアを開発するチームと保守するチームは異なります。開発者には、保守しやすいコードを書くインセンティブがありません。ソフトウェアは不完全な状態で納品されることが多く、ほとんどの場合、保守チームが修正しなければならないバグが含まれています。ソフトウェアのメンテナンスには、当初は新機能の開発が含まれることがよくありますが、製品の寿命が近づくにつれて、メンテナンスは必要最低限にまで削減され、製品が廃止される前に完全に中止されます。
各メンテナンスサイクルは、通常エンドユーザーからの変更要求から始まります。その要求は評価され、実装が決定された場合、プログラマーは変更を実装する前に既存のコードの動作を調査・理解します。既存の機能が維持され、必要な新機能が追加されていることを確認するためのテストが、メンテナンスコストの大部分を占めることがよくあります。
ソフトウェア保守は、コストの大部分を占めるにもかかわらず、ソフトウェアライフサイクルの他のフェーズほど十分に研究されていません。1980年代以降、ソフトウェア保守に関する理解は大きく変わっていません。ソフトウェア保守は、予防的なものか事後的なものか、また機能の追加を目的とするか既存機能の維持を目的とするかによって、いくつかの種類に分類できます。後者は、一般的に環境の変化に直面した際に行われます。
1970年代初頭、企業はソフトウェア開発チームをサポート業務から解放するため、ソフトウェアメンテナンスを自社のエンジニアチームに分離し始めました。[1] 1972年、RG・キャニングは「メンテナンスの氷山」を出版し、ソフトウェアメンテナンスはソフトウェア開発の延長線上に、既存のシステムという新たな要素を加えたものであると主張しました。[1]ソフトウェアメンテナンスの分野は、それ以来ほとんど変わっていません。[2] 21世紀のイノベーションの一つは、企業が意図的に不完全なソフトウェアをリリースし、リリース後に完成させる計画を立てることです。この種の変更、そして機能を拡張する他の変更は、メンテナンスではなく、ソフトウェアの進化と呼ばれることがよくあります。 [2]

テストと品質保証にもかかわらず、事実上すべてのソフトウェアには、システムが意図したとおりに動作しないバグが含まれています。これらのバグが見つかった場合、リリース後のメンテナンスで修正する必要があります。 [3]ほとんどのソフトウェアは、既存の商用オフザシェルフ(COTS) およびオープンソースソフトウェアコンポーネントとカスタム記述コードを組み合わせたものです。 COTS およびオープンソースソフトウェアは通常、時間の経過とともに更新されるため、メンテナンスの負担は軽減されますが、これらのソフトウェアコンポーネントへの変更は最終製品で調整する必要があります。[4]指定された要件を満たすことに重点が置かれたソフトウェア開発とは異なり、ソフトウェアメンテナンスは、ユーザーからの要求やバグの検出などのイベントによって駆動されます。[5]その主な目的は、通常、要件の変化に直面してもソフトウェアの有用性を維持することです。[6]
ソフトウェア開発ライフサイクルの一部として捉えると、保守はサイクルの最後であり、通常は最も長いフェーズとなり、[7] [8]ライフサイクルコストの80~90%を占めます。[9]他のモデルでは、保守をソフトウェア開発とは別のものとして捉え、ソフトウェア保守ライフサイクル(SMLC)の一部として捉えています。[8] SMLCモデルには通常、コードの理解、修正、再検証が含まれます。[8]

ソフトウェアは不完全な状態で納品されることがよくあります。開発者は、時間や予算を超過するよりも、不完全な製品で受ける影響の方が少ないため、時間や資金が尽きるまで製品をテストします。[10]開発チームから保守チームへの移行は、既知の問題や検証テストのリストがないため、非効率的になることが多く、保守チームはそれらを再作成する可能性があります。[11]リリース後、開発チームのメンバーは異動になるか、何らかの理由で利用できなくなる可能性があります。保守チームは、リリース後1年間は、技術サポートと開発中に残った欠陥の修正のために、追加のリソースを必要とします。[10]
ソフトウェアは、リリース後、当初は機能強化の期間を経る場合があります。ユーザーからのフィードバックに基づいて新機能が追加されます。ある時点で、企業は機能改善を行うのはもはや利益にならないと判断し、サポートをバグ修正と緊急アップデートに限定する場合があります。専門知識の不足やソフトウェアの老朽化によるアーキテクチャの劣化により、変更はますます困難で費用もかかります。製品がメンテナンスされなくなり、この限られたレベルのアップデートさえ受けられなくなると、一部のベンダーは、製品がますます敬遠される可能性が高くなるにもかかわらず、できるだけ長くソフトウェアから収益を上げようとします。最終的には、ソフトウェアは市場から撤退しますが、引き続き使用される可能性があります。このプロセスの間に、ソフトウェアはレガシーシステムになります。[12]
変更サイクルの最初のステップは、顧客から変更要求を受け取り、それを分析して問題を確認し、変更を実施するかどうかを決定することです。[13]これには複数の部門からの意見が必要になる場合があります。たとえば、マーケティングチームは、変更によってより多くのビジネスがもたらされると予想されるかどうかを評価するのに役立ちます。[14] ソフトウェア開発の労力見積もりは、保守変更要求を含めて難しい問題ですが、[15]要求が高すぎるか実行不可能な場合は拒否される可能性があります。[16] 要求を実施することが決定された場合、スケジュールされたリリースに割り当てて実装できます。[16]アジャイル方法論には保守フェーズはありませんが、[17] 変更サイクルはスクラムスプリントとして制定できます。[18]
既存のコードを理解することは、コードを変更する前に不可欠なステップです。[2]理解の速さは、コードベースとプログラマーのスキルの両方に依存します。[19]目的に合った明確な関数名や変数名を使用するなどのコーディング規約に従うことで、理解が容易になります。[20]コードが複数回実行される場合にのみ条件付きループ文を使用し、実行されないコードを削除することでも、理解しやすさが向上します。 [21]経験豊富なプログラマーは、コードが高レベルで何をするかを理解するのが容易です。 [ 22 ] ソフトウェアの視覚化は、このプロセスを高速化するために使用されることがあります。[23]
コードの変更はあらゆる方法で行われる可能性があります。一方では、コードドキュメントを更新する十分な時間を与えられずに、場当たり的に応急処置を施すことが一般的です。[24]一方では、最上位レベルの要件ドキュメントを変更し、その変更をシステムの下位レベルに伝播させることで、しっかりと構造化された反復的な機能強化を開始できます。[25]変更には、多くの場合、コードのリファクタリング(機能を変えずに構造を改善する)と再構築(構造と機能を同時に改善する)が含まれます。[26]商用ソフトウェアとは異なり、フリーソフトウェアやオープンソースソフトウェアの変更サイクルは、主にコーディングとテストに限定されており、ドキュメントは最小限です。オープンソースソフトウェアプロジェクトでは、代わりにメーリングリストや多数の貢献者に頼ってコードベースを理解し、効率的にバグを修正しています。[27]
メンテナンスのもう一つの問題は、コードを変更するたびにほぼ必ず新しいバグや予期せぬ波及効果が発生し、再度の修正が必要になることです。[2]変更があった場合、ソフトウェア全体を再検証する必要があるため、安全性が重要なコードのメンテナンスリソースの大部分はテストに費やされる可能性があります。[28] 再検証には、コードレビュー、ユニットテストのサブセットを含む回帰テスト、統合テスト、システムテストなどが含まれます。[26]テストの目的は、以前の機能が保持され、新しい機能が追加されたことを確認することです。[29]
ソフトウェアメンテナンスの主な目的は、製品がユーザビリティ要件を継続的に満たし続けることを保証することです。場合によっては、当初想定されていた範囲を超えて製品の機能を拡張することを意味することもあります。[30]
ISO / IEC 14764仕様によれば、ソフトウェアメンテナンスは4つのタイプに分類できます。[31]
ある推計によると、機能強化(後者の2つのカテゴリ)はソフトウェアメンテナンスの約80%を占めています。[35]
保守性とは、既存の機能を壊すことなくソフトウェアを簡単に変更できる品質のことです。[31] ISO/IEC 14764仕様によれば、リリース前にソフトウェアの保守性を保証する活動は、ソフトウェア保守の一部です。[5]多くのソフトウェア開発組織は、長期的なコストが増加するにもかかわらず、保守性を無視しています。[36] 技術的負債は、プログラマが、多くの場合、怠惰または期限に間に合わせる緊急性から、コードに保守性を組み込むのではなく、急ごしらえの解決策を選択した場合に発生します。[37]一般的な原因は、ソフトウェア開発の労力見積もりを過小評価し、開発に割り当てられるリソースが不十分になることです。[38]重要な側面の1つは、既存の機能が変更によって損なわれたかどうかを検出できる大量の自動化されたソフトウェアテストを用意することです。 [31]
保守性指標は、コード行数の尺度、McCabe の尺度、およびHalstead の複雑性の尺度から特定の式を使用して計算できます。
保守性の測定と追跡は、システムの「コード エントロピー」または整合性の低下の傾向を軽減または逆転させ、コードを変更するよりもコードを書き直す方が安価でリスクが低くなる時期を示すことを目的としています。
保守性に関する課題は、多くのソフトウェアエンジニアリングのコースで保守性が重視されておらず、明確で変更不可能な仕様を持つ単発課題が与えられていることです。[39]ソフトウェアエンジニアリングのコースでは、現実世界で発生するような複雑なシステムは扱われません。[40]ソフトウェアの保守責任を負わないことを知っている開発エンジニアには、保守性を組み込むインセンティブがありません。[2]
メンテナンスはソフトウェアエンジニアにとってやりがいのない仕事だと思われがちで、メンテナンスに配属されたら辞めてしまう可能性が高かった。[41] [42]メンテナンスの賃金は、ソフトウェア開発における同等の仕事よりも低い場合が多い。[42]この仕事は臨時労働者やスキルの低いスタッフに割り当てられることが多いが、[2] [43]メンテナンスエンジニアは、時代遅れの技術に精通している必要があることもあり、開発者よりも年齢が高いのが一般的である。[43] 2008年には、米国で働く130万人のソフトウェアエンジニアとプログラマーのうち約90万人がメンテナンスを行っていた。[44]
企業はメンテナンス用に別のチームを立ち上げ、その結果、この作業を別の会社にアウトソーシングするようになり、21 世紀に入ると、元の会社の一部または別の事業体として、作業を他の国にオフショア化することもありました。 [45] [9]アウトソーシングの一般的なソースは、米国、英国、日本、オーストラリアなどの先進国ですが、宛先は通常、中国、インド、ロシア、アイルランドなどの低コストの国です。[46]オフショアリングの理由には、人件費の低さを利用すること、24 時間サポートを可能にすること、開発者の時間的プレッシャーを軽減すること、サポートを製品の市場に近づけることなどがあります。[47]オフショアリングの欠点には、タイムゾーンや組織の分離、文化の違いなどの要因の形で生じるコミュニケーションの障壁があります。 [9] 多くの雇用主がメンテナンスを低スキル作業であり、オフショアリングに最も適したソフトウェア開発段階であると考えているにもかかわらず、[9] [48]メンテナンスには顧客との密接なコミュニケーションと迅速な対応が必要であり、[9]
ソフトウェア工学において、 「レガシーシステム」という用語は固定的な意味を持ちませんが、多くの場合、大規模で変更が困難でありながら、現在のビジネスニーズにも不可欠な古いシステムを指します。レガシーシステムは、時代遅れのプログラミング言語で記述され、ドキュメントが不足し、長年の変更によって構造が劣化しており、運用維持のために専門家に依存していることがよくあります。[49]これらのシステムを扱う場合、ある時点で技術的負債が蓄積されすぎて、メンテナンスが現実的または経済的ではなくなります。[12]その他の選択肢としては、以下が挙げられます。
ソフトウェア開発リソースの大部分を占めるにもかかわらず、保守はソフトウェア開発の中で最も研究されていないフェーズです。[56] [57]多くの文献は、保守しやすいコードを開発する方法に焦点を当てており、エンジニアが保守性を優先するように動機付けることについてはあまり焦点が当てられていません。[58] 2020年現在[update]、保守の労力を削減するためのコードリファクタリングの自動化ソリューションは、研究が活発に行われている分野です。[59]機械学習による保守性評価の強化も同様です。[60]