【結論】
・非機能要件とは、拡張性やテストのしやすさなど、ユーザーに直接役立つ機能とは別の要件
・非機能要件の観点には、「変更容易性」「相互運用性」「効率性」「信頼性」「テスト容易性」「再利用性」が挙げられる
・非機能要件が十分に考慮されていないと、パフォーマンスの低下や開発コストの増大など、様々な影響が出る為、「機能要件」同様に設計段階で考慮する必要がある
【目次】
【本題】
機能では無い要件
ソフトウェアを設計する上で、どういった機能を実装したいのか(ユーザーにどういった価値を提供したいか)を具体的に定義したものを「機能要件」と呼びます。
それと対照的に取り上げられるのが「非機能要件」です。
非機能要件とは、名前の通り、ユーザーに直接役立つ機能とは別の要件です。
具体的には、拡張のしやすさ・テストのしやすさ等が挙げられます。
こういったものは、ソフトウェアの付加価値を高めることに直接貢献しにくいので、軽視されがちです。
しかし、非機能要件が十分に考慮されていない場合、パフォーマンスの低下や開発コストの増大など、様々な問題が生じる可能性が高まります。
その為、機能要件と同様に設計段階で考慮する必要があります。
非機能要件の観点
非機能要件の観点は、「変更容易性」「相互運用性」「効率性」「信頼性」「テスト容易性」「再利用性」の6つがあります。
「変更容易性」
コードがどれだけ簡単に変更できるかを指します。
ソフトウェアはリリース後も、障害への対応や、ユーザーからの要望を受けた追加開発などが発生します。
また、営利目的でリリースしたサービスであれば、出来るだけ継続してユーザーに使われることを目指すはずなので、場合によっては長期間保守を行う必要があります。
こういったコードの修正を要求される場面で、迅速かつ正確に対応を行う為には、コードを容易に変更できる設計にする必要があります。
モジュール間の結合度合いが強くならないようにして拡張性を高めたり、コード変更時に他のモジュールへの影響が最小になるようなアーキテクチャを採用して保守性を高めるなど、様々な手法が存在します。
「相互運用性」
他のソフトウェアとデータのやり取りが出来るかを指します
ソフトウェアは、独立して成り立っている訳ではなく、他のシステムや環境のもとで動作しています。
また、他のソフトウェアとデータのやり取りが出来ると、そのソフトウェアが有する機能を簡単に獲得することが出来ます。
その為、他のソフトウェアとのやり取りが行える事は、非常に重要になります。
通信プロトコルやデータ形式などを、広く普及している標準規格を採用したり、データのやり取りを仲介するソフトウェアを利用するなどで対策を講じます。
「効率性」
リソースを効率よく利用しているかを指します。
ソフトウェアが動作する上で必要なCPUやメモリなどは、いずれも有限のリソースなので、非効率な使い方をすると、パフォーマンスが低下します。
こういった問題を防ぐ為には、既存のリソースの性能を最大限引き出して、効率的に運用する必要があります。
モジュール間の責務を分散させたり、結合を適切に行うなどが対策として挙げられます。
ただ使用量を節約するのではなく、今ある全てのリソースを最大限に活用する視点が必要です。
「信頼性」
不正な操作からソフトウェアを保護出来るかを指します。
インターネット上にサービスを公開した場合、悪意のある人がソフトウェアに不正アクセスを行い、被害をもたらす可能性があります。
それ以外にも、ユーザーが意図せず行った誤った操作によって、ソフトウェアが正常に動作しなくなるケースも存在します。
そういった予期しない操作からソフトウェアを守る必要があります。
ソフトウェアごとに求められる信頼性の度合いは異なるので、適切な設計を選択する必要があります。
「テスト容易性」
効果的にテストが行えるかを指します。
効果的というのは、ソフトウェアを細部まで漏れなくチェックできるという事です。
質の高いテストが行えれば、それだけソフトウェアの品質向上に繋がります。
対策としては、モジュール間の依存関係を排除して、小さい単位でテスト出来るようにするなどがあります。
「再利用性」
コードが再利用しやすいかを指します。
一から全てを開発するより、既存のコードを再利用した方がコストも低く済みますし、正常に動作してきた実績があるコードであれば、品質も担保できます。
他で利用できそうな部分をモジュール化しておくことで対応したりします。
プロジェクト/機能によって必要な水準は異なる
なお、これらの要件は、いずれも最大水準を満たそうとするとコストが増大してしまい、かえって開発を妨げます。
なので、プロジェクトや実装する機能に応じて、適切な水準を見極める必要があります。
例えば、大規模な業務システムであればサービス停止は許されないですが、個人用のサービスであれば、それほどの持続性は求められませんなどです。
他には、決済機能はトラブルが発生すると非常に危険なので最大限の取り組みをするものの、お知らせの通知機能などはトラブル発生時の影響が軽微なので、それと同じ水準にする必要が無いといった考え方です。
これらも考慮した上で、非機能要件を定める必要があります。
参考情報
書籍「プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則」
《今日の学習進捗(3年以内に10000時間に向けて)》
CTOを交えたMTGにて、システム面での品質を向上させる為の、今後の取り組みについて話し合った。 当面はテストコードの拡張をメインに改善を行う事になったが、テストコードの実装についてはやや苦手意識がある。 良い機会なので、RSpecの技術書を読むなどして、テストコードの実装スキルを高めたい。
なお、運用面でも、レビューの観点を取りまとめてチェックの抜け漏れを防ぐ取り組みも実施する事になった。 レビューの観点を定めるにあたり、設計に関する原則などを参考にしようと試みたが、いずれも抽象的な内容なので、そのままチェックリストとして運用しても形骸化しそうな印象を受けた。 やはり過去の障害の原因分析などを行い、業務特性に合わせて地道にカスタマイズしたものを作るしか無いと考えている。
学習開始からの期間 :241日
今日までの合計時間:2302h
一日あたりの平均学習時間:9.6h
今日までに到達すべき目標時間:2201h
目標との解離:101h
「10,000時間」まで、
残り・・・「7698時間!」