#はじめに
研究者として色々ソフト開発してきたが、やはり「保守性」と「活用可能性」が重要だと思う。とは言うものの「保守性の高いコード」や「活用可能性の高いコード」って、どんなもの?と聞かれて即答するのが難しいことに気づいた。そこで「ソフトウェア保守開発」や「リーダブルコード」など多数の書籍や、GoogleのDevOpsドキュメント、ネット上にアップされている各種の先達の意見を参考に、自分なりに整理してみた。
保守性が高いソフトウェア
最初に保守性の方から考えてみたが、実は問題が無いというのが大事だったりする。よって、これから要件を出すのは難しい。
- ISO14764での適応保守、是正保守、緊急保守、保守性、修正依頼、問題報告、予防保守、ソフトウェア保守、ソフトウェア引き継ぎなどを阻害せず、効率的に行える。
- OSやライブラリなど開発環境の変更があっても問題なく使い続けられる。
- OSやライブラリなど実行環境の変更があっても問題なく使い続けられる。
- 入力データやユーザが変わっても問題なく使い続けられる。
- 新しい使い方や使用条件に対応して、素早く修正対応できる。
- 開発後長い期間たってから判明した不具合やバグを、素早く修正対応できる。
- 開発担当者が変わっても、ソフトウェアの中身に関する知識を短期間に継承できる。
保守性の低いコードの例
一方で、保守性の低いコードは、自分の経験を含め実例が多数ある。
よって反面教師としてわかりやすいので以下に列挙する。
- スパゲッティコード。複雑に絡み合って、一部の修正が予想もしない他の場所に影響する。
- ブラックボックスがある。何をやっているのか今では誰も分からないコードを含んでいる。
- 個々の関数やモジュールが巨大で、同じメモリ領域を複雑に使用したコードになっている。
- 似たような関数が多数存在し、使い方の違いが分かりにくい。全く同じコードが何回も出てくる。
- オブジェクト指向が採用されておらず、変数や関数の関連性が不明。
- 構造体やクラス定義が恣意的で、何を表しているのか開発者以外に分からない。
- コメントが無い。
- 関数名、変数名、モジュール名が恣意的で、開発者以外に中身が想像できない。
- トリッキーなアルゴリズムが採用されており、修正が困難である。ポインタマジックなど。
- 強い外部依存があり、依存対象のライブラリ等が明示されておらず、最新版に対応していない。
- ドキュメントがソースコードしか無い。
- 構成管理がなされていない。複数のバージョンが並立している。
- 保守履歴が記録されていない。
- テストコードが整備されておらず、改修後の検証が困難である。
- 最初に開発されてから一度もレビューされていない。
- プログラム内に既に使用停止になったコードが多数残っている。
- コード量が無駄に大きい。
- 脆弱性が放置されている。
- エラーハンドリングが適当に処理されている。例外を無視など。
活用可能性が高いソフトウェア
活用可能性は、ISO14764での改良保守、完全性保守に加えて、拡張可能性、API整備、マイクロコード化などだが、保守性ほどには整理されていない。
- 別のアプリケーションと入出力データを容易に連携可能である。
- APIリファレンスやチュートリアルなどドキュメントが整備されており、ソフトウェアの中身を知らなくても容易に機能を利用可能である。
- ソフトウェアの機能や内部構成に関するドキュメントが整備されており、機能拡張や修正が容易である。
- 開発当初に想定した規模を大きく超える入力データや計算内容にも柔軟に対応できる。
- デファクト・デジュールな規格に準拠しており、手を加えなくても外部ソフトウェアと連携可能である。
- コードの必要な部分を切り出して使うのが容易である。
活用可能性の低いコードの例
保守性同様にこちらも悪い例を列挙してみる。
- APIが整備されておらず、外部のソフトから利用することができない。
- ドキュメントはソースコードのみ。
- メモリ確保やディスク管理が固定的でスケーラビリティが無い。ループが固定的で暗黙に上限が設定されている。
- 機能を制限するパラメータがコード内部にハードコーディングされている。
- 特定の漢字コードを前提にしていて、暗黙にそれを前提にした処理を行なっている。
- 特殊な外部アプリや、ライブラリ、OSバージョンに依存しており、分離して利用できない。
- 入出力データの形式が特殊で、利活用に手間がかかる。また形式に関する分かりやすい資料が無い。
- クラスライブラリが整理されていない。似たようなクラスが複数あり、違いが分からない。
- アルゴリズムにスケーラビリティが無く、扱うデータ量に応じて指数関数的に計算時間が伸びる。または計算不可能。
- GUIとビジネスロジックが密接に絡んでいて、別々に利用できない。UIのコールバックに計算を入れ込むなど。
- 利用範囲や制約、副作用が不明で再利用性の低い関数、構造体、クラスから構成されている。
おわりに
いずれも「言うはやすし」ではあるが、列挙してみることは大事かなと思った。
他に追加すべき良好事例・悪例があればコメントください。