2012年12月29日土曜日

ソフトウェア開発プロセスにdoxygenをうまく導入できないだろうか…。

はじめに

 ソフトウェア開発において、突然の開発要件の追加やバグの修正のために、ソースコードを変更したけれど、ドキュメントを更新していなかったということがしばしば発生する。企業などが業務としてソフトウェア開発を行う場合には、限られた工数で高い機能と品質を実現する必要があるため、ドキュメントとソースコードの内容に齟齬があると、調査に余計な工数を必要としたり、新たなバグを混入するリスクを高めることになる。
 こうした課題に対して、ソフトウェア開発プロセスにおけるサポート・プロセスの作業を詳細に規定することによって、ドキュメントとソースコードの変更内容のトレーサビリティを管理しようと試みることがある。こうしたアプローチは誤りではないが、サポート・プロセスの詳細化や厳格化は、結果的に生産性の低下やコストの増加を招くリスクがあることも事実である。
 ここでは、とくにソフトウェア詳細設計書とソースコードに焦点を当て、ソフトウェア・エンジニアリング・プロセスの観点から、この課題の改善策を考察する。


なぜdoxygenを使うのか?

 そもそも、ソフトウェア詳細設計書とソースコードの内容に齟齬が生じてしまう要因は、それらに論理的な関係はあっても、物理的な関係がないことにあると考える。物理的な関係とは、ソースコードを変更すると自動的にソフトウェア詳細設計書へ反映できたり、またはその逆のことができることを指す。そこで、ここでは、ソフトウェア詳細設計書とソースコードに物理的な関係を持たせる方法を考察する。
 例としては、ソースコードを自動生成できるIDEを導入したり、モデルベース開発の手法を導入するといった方法が考えられる。しかし、ここでは、小規模なプロジェクトや現在進行中のプロジェクトにも比較的に導入が容易な方法として、古くから存在するdoxygenというツールを活用することを検討したい。
 doxygenでは、ソースコードにコメントの形式でドキュメントを埋め込むことになるため、齟齬が生じる問題が発生しにくくなることを期待できる。


どのようにdoxygenを使うのか?

 一方で、doxygenを導入すればソフトウェア開発の全てがうまくいくというものでない。doxygenはあくまでもソースコードに記述したコメントからHTMLやRTF形式のドキュメントを生成するツールにすぎないため、ユースケースやシーケンスなどのUMLを用いたソフトウェア・アーキテクチャ設計を実施することはできない。そこで、ここでは、doxygenをソフトウェア開発プロセスに導入するための方法を考察する。

 ここでは、以下のようなアクティビティを含むソフトウェア・エンジニアリング・プロセスを対象とする。
  • ソフトウェア要求定義
  • ソフトウェア・アーキテクチャ設計
  • ソフトウェア詳細設計
  • 実装
  • 単体テスト
  • ソフトウェア結合テスト
  • ソフトウェア総合テスト
 また、上記のプロセスのうち、ソフトウェア・アーキテクチャ設計から実装までのアクティビティは以下のようなタスクを含むとする。

  • ソフトウェア・アーキテクチャ設計のタスク
    • 設計条件の確認
ソフトウェア・アーキテクチャを設計する上で重要なソフトウェア機能要求、非機能要求および制約条件などをリストアップする。
    • ソフトウェア構成の設計
上記でリストアップした要求や制約条件とハードウェア構成などをもとに、レイヤと機能ユニットの分割方針を策定する。また、分割方針に従って、具体的にレイヤと機能ユニットの分割を行い、各レイヤと各機能ユニットの役割を明確化する。機能ユニットの分割は、クラスなどの静的構成とスレッドなどの動的構成の両方について行う。
    • ソフトウェア全体の振る舞いの設計
上記で分割した機能ユニット間の処理シーケンスを策定する。
    • インタフェースの設計
上記で策定した機能ユニット間の処理シーケンスをもとに、各機能ユニットのインタフェース仕様を策定する。
    • ソフトウェア・アーキテクチャ設計書の作成
上記までの検討結果を整理・体系化してソフトウェア・アーキテクチャ設計書を作成し、レビューを実施する。
  • ソフトウェア詳細設計のタスク
    • プログラムユニット分割
ソフトウェア・アーキテクチャ設計で策定した各機能ユニットのインタフェース仕様に対して、処理内容をリストアップしていき、それらをプログラムユニットとする。また、各プログラムユニットのインタフェース仕様を策定する。
    • プログラムユニット設計
上記で分割した各プログラムユニットの処理内容を詳細化する。プログラムユニットの処理内容は箇条書きで構わないが、処理内容が複雑で誤解を招く恐れがある場合はフローチャートを作成する。
    • ソフトウェア詳細設計書の作成
上記までの検討結果を整理・体系化してソフトウェア詳細設計書を作成し、レビューを実施する。
  • 実装のタスク
    • プログラムユニットの実装
ソフトウェア詳細設計書に従ってソースコードを作成し、レビューを実施する。

 現実のソフトウェア開発では、上記のプロセスに従ってソフトウェア・アーキテクチャ設計書までは適切に作成していても、様々な理由でソフトウェア詳細設計書は作成していないことがしばしばあると思われる。そこで、ここでは、以下のようにdoxygenを導入して、ソフトウェア詳細設計と実装を行うことを検討したい。

  • ソフトウェア詳細設計のタスク
    • プログラムユニット分割
ソフトウェア・アーキテクチャ設計で策定した各機能ユニットのインタフェース仕様をソースコードに実装する。このとき、ファイルヘッダや関数ヘッダをdoxygenのコメントスタイルで作成し、各インタフェース仕様の説明を記述する。
次に、各機能ユニットのインタフェースに対して処理内容をリストアップして関数ヘッダに追記していき、それらをプログラムユニットとする。各プログラムユニットのインタフェース仕様もソースコードに実装して、関数ヘッダをdoxygenのコメントスタイルで作成し、各インタフェース仕様の説明を記述する。  
この時点では、インタフェース仕様のみを実装し、実処理は実装しない。
    • プログラムユニット設計
上記で分割した各プログラムユニットの処理内容を詳細化して関数ヘッダに追記する。処理内容が複雑で誤解を招く恐れがある場合は別途フローチャートを作成し、関数ヘッダにはリンク情報を追記する。
    • ソフトウェア詳細設計書の作成
ソースコードに記述したファイルヘッダや関数ヘッダなどのコメントからdoxygenを使ってドキュメントを生成し、詳細設計書を作成する。また、レビューを実施する。
  • 実装のタスク 
    • プログラムユニットの実装
ソースコードに記述したファイルヘッダや関数ヘッダなどのコメントに従って実処理を実装する。また、レビューを実施する。

 ファイルヘッダや関数ヘッダをdoxygenのコメントスタイルで作成する際、なにを記述するべきなのかについては次の機会に検討する。

2012年11月1日木曜日

ソフトウェア・アーキテクチャ設計でやるべきことってなんだろう…。

本当はもっと纏まった文章を書くつもりだったのですが、何時まで経っても纏められそうにないし、少し荒削りでも早く出すことが大事だと思いましたので、駄文ですがご容赦ください。書き出しが唐突に始まりますが、これもご容赦ください。m(_ _)m


以下のようなアクティビティを含むソフトウェア・エンジニアリング・プロセスで、ソフトウェア・アーキテクチャ設計のアクティビティでやるべきタスクについて考察してみた。

  • ソフトウェア要求定義
  • ソフトウェア・アーキテクチャ設計
  • ソフトウェア詳細設計
  • 実装
  • 単体テスト
  • ソフトウェア結合テスト
  • ソフトウェア総合テスト

ソフトウェア・アーキテクチャ設計のタスク

設計条件の確認

ソフトウェア・アーキテクチャを設計する上で重要なソフトウェア機能要求、非機能要求および制約事項をリストアップする。このとき、リストアップする要求や制約事項に漏れがあると、後の工程でソフトウェア・アーキテクチャの大規模な見直しが必要となるリスクを高めることになるため、漏れを防止するという観点から適切にレビューを実施することが重要である。
 また、ここで策定するソフトウェア・アーキテクチャは、その後23年は大きく見直すことなく使い続けることも目標とするため、将来的に導入することが予想される要求や制約事項も可能な限りリストアップする。

ソフトウェア構成の設計

上記でリストアップした要求や制約事項とハードウェア構成などをもとに、レイヤと機能ユニットの分割方針を策定する。レイヤの分割方針では縦方向の役割分担の考え方を策定し、機能ユニットの分割方針では各レイヤにおける横方向の機能分担の考え方を策定する。また、機能ユニットの分割方針は、クラスなどの静的構成とスレッドなどの動的構成の両方について策定する。
 策定した分割方針に従って、具体的にレイヤと機能ユニットの分割を行い、各レイヤと各機能ユニットの役割を明確化する。

ソフトウェア全体の振る舞いの設計

上記で分割した機能ユニット間の処理シーケンスを策定する。全てのユースケースに対して処理シーケンスを作成する必要はないが、代表的なユースケースや特異なユースケースに対する処理シーケンスは必ず作成する。ここでも、重要なユースケースに対する処理シーケンスの検討漏れを防止するという観点から適切にレビューを実施することが重要である。

インタフェースの設計

上記で策定した機能ユニット間の処理シーケンスをもとに、各機能ユニットのインタフェース仕様を策定する。

ソフトウェア・アーキテクチャ設計書の作成

上記までの検討結果を整理・体系化して、ソフトウェア・アーキテクチャ設計書を作成する。また、リストアップした要求や制約事項と検討したソフトウェア・アーキテクチャとの間に不整合はないかという観点からレビューを実施する。


ソフトウェア詳細設計のタスク

プログラムユニット分割

ソフトウェア・アーキテクチャ設計で策定した各機能ユニットのインタフェース仕様に対して、処理内容をリストアップしていき、それぞれをプログラムユニットとする。このとき、ソフトウェア・アーキテクチャ設計では検討しなかった全てのユースケースに対して処理シーケンスを作成し、インタフェース仕様を策定しておく。リストアップした処理内容に同じものがあれば、プログラムユニットを共通化する。また、各プログラムユニットのインタフェース仕様も策定する。

プログラムユニット設計

上記で分割した各プログラムユニットの処理内容を詳細化する。プログラムユニットの処理内容は箇条書きで構わないが、処理内容が複雑で誤解を招く恐れがある場合はフローチャートを作成したほうがよい。

ソフトウェア詳細設計書の作成

上記までの検討結果を整理・体系化して、ソフトウェア詳細設計書を作成する。また、プログラムユニットの分割が最適に行われているかという観点からレビューを実施する。

実装のタスク

プログラムユニットの実装

ソフトウェア詳細設計書に従って、ソースコードを作成する。また、レビューを実施する。


  現実のソフトウェア開発では、ソフトウェア・アーキテクチャ設計書は作成していても、ソフトウェア詳細設計書は作成していなかったり、作成していても更新できていないためにソースコードと内容が乖離していることがあると思われる。こうした課題の改善策は別の機会に考察する。