ソフトウェア保守とは、ソフトウェアの納品後にソフトウェアを修正することを指します。
ソフトウェア保守は、新規開発に比べてスキルレベルが低く、やりがいも少ないとみなされることが多い。そのため、アウトソーシングやオフショアリングの対象となることが多い。通常、ソフトウェア開発チームと保守チームは別組織である。開発者は、保守しやすいコードを書くインセンティブに欠ける。ソフトウェアは不完全な状態で納品されることが多く、保守チームが修正しなければならないバグがほぼ必ず含まれている。ソフトウェア保守は、当初は新機能の開発も含まれることが多いが、製品のライフサイクルが終わりに近づくにつれて、保守は最小限にまで縮小され、製品が廃止される前に完全に停止される。
各保守サイクルは、通常エンドユーザーからの変更要求から始まります。その要求が評価され、実装が決定された場合、プログラマーは変更を実装する前に既存のコードを精査し、その動作を理解します。既存の機能が維持され、必要な新機能が追加されていることを確認するためのテストは、多くの場合、保守コストの大部分を占めます。
ソフトウェア保守は、ソフトウェアライフサイクルの他のフェーズほど研究が進んでいないにもかかわらず、コストの大部分を占めています。1980年代以降、その理解は大きく変わっていません。ソフトウェア保守は、予防的か事後的か、機能を追加するのか既存の機能を維持するのか(後者は通常、環境の変化に対応して行われる)によって、いくつかの種類に分類できます。
1970年代初頭、企業はソフトウェア保守を独自のエンジニアチームに分離し、ソフトウェア開発チームをサポート業務から解放し始めた。[ 1 ] 1972年、RG Canningは「保守の氷山」を出版し、その中でソフトウェア保守は既存システムという追加の入力を伴うソフトウェア開発の拡張であると主張した。[ 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 ]
メンテナンスにおけるもう1つの問題は、コードへの変更のほぼすべてが新しいバグや予期しない波及効果をもたらし、修正の別のラウンドが必要になることです。[ 2 ]安全性が重要なコードの場合、変更があった場合はソフトウェア全体を再検証する必要があるため、テストがメンテナンスのリソースの大部分を消費する可能性があります。[ 28 ]再検証には、コードレビュー、ユニットテストのサブセットを使用した回帰テスト、統合テスト、およびシステムテスト が含まれる場合があります。[ 26 ]テストの目的は、以前の機能が維持され、新しい機能が追加されていることを確認することです。[ 29 ]
ソフトウェア保守の主な目的は、製品がユーザビリティ要件を満たし続けることを保証することです。場合によっては、これは製品の機能を当初想定されていた範囲を超えて拡張することを意味するかもしれません。[ 30 ]
ISO / IEC 14764 仕様によれば、ソフトウェア保守は 4 つのタイプに分類できます。[ 31 ]
一部の推定によると、機能強化(後者の2つのカテゴリ)はソフトウェア保守の約80パーセントを占めている。[ 35 ]
保守性とは、既存の機能を損なうことなくソフトウェアを容易に変更できるソフトウェアの品質のことです。[ 31 ] ISO/IEC 14764 仕様によれば、リリース前にソフトウェアの保守性を確保するための活動は、ソフトウェア保守の一部とみなされます。[ 5 ]多くのソフトウェア開発組織は、保守性を軽視していますが、そうすると長期的なコストが増加します。[ 36 ]プログラマーが、多くの場合怠惰や締め切りに間に合わせる必要性から、保守性をコードに組み込むのではなく、手っ取り早く粗雑な解決策を選択した場合に、技術的負債が発生します。[ 37 ]一般的な原因は、ソフトウェア開発の工数見積もりの過小評価であり、開発に割り当てられるリソースが不足します。[ 38 ]重要な側面の 1 つは、変更によって既存の機能が損なわれていないかどうかを検出できる、大量の自動化されたソフトウェア テストを用意することです。 [ 31 ]
保守性指標は、コード行数、マッケイブ指標、ハルステッド複雑度指標などの特定の計算式を用いて算出できます。
保守性の測定と追跡は、システムの「コードエントロピー」や整合性の低下傾向を軽減または逆転させることを目的としており、コードを変更するよりも書き換える方が安価でリスクが低い時期を示すものです。
保守性に関する課題は、多くのソフトウェアエンジニアリングコースがそれを重視せず、明確で変更不可能な仕様を持つ一度きりの課題を与えることです。[ 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年現在保守作業を削減するためのコードリファクタリングの自動化ソリューションは活発な研究分野であり[ 59 ] 、機械学習による保守性評価の強化も同様である[ 60 ]。