Software Engineering
オープンソース開発におけるソフトウェアの工学的側面
Paul Vixie
ポール・ヴィクシー
Translation by Akira Kurahone
「プログラムを書く」ことだけがソフトウェア開発ではない。にもかかわらず、オープンソースプロジェクトでは多くの場合、プログラムは単に書かれ、単に配布されている。とはいえ、ソフトウェア工学的に作成されなければ、幅広いユーザに受け入れてもらえないわけでもない。これが事実であることを示す例はいままでにもたくさんある。そこで、本章では、通常のソフトウェア開発で実践される工学的工程をまず検討し、そのうえで、それらの工程がオープンソースのコミュニティでどのように実践されているかについて考察してみたい。そして最後に、そこに現われた違いの意味について考えてみることにする。
ソフトウェア開発の工程
ソフトウェアの開発には、次に示す七つの工程が含まれるのが普通である。
- 要求分析
- システム設計
- 詳細設計
- 実装
- 結合テスト
- 総合テストおよび実地検証
- 保守
この一連の流れでは、ある工程の作業が実質的に完了しない限り、次の工程に進むことはできない。また、ある工程で変更が加えられた場合、それに依存したり、それを利用したりする部分は、その変更が適切に反映されるように再検討されなければならない。システムがモジュール化されている場合は、依存される側のモジュールの設計開発を、依存する側の設計を待たずに先行させることもできる−こうした手順での開発は、アドバンストデベロップメント(advanced development)と呼ばれている。
ソフトウェア開発を工学的に進めていくうえで欠かせない要素のひとつは、レビューである(レビューとは、客観的な知識を集めて、設計品質およびそれを実現するための工程からソースコードのレベルに至るまでを評価し、改善点を提案し、次の工程に進みうる状態にあることを確認する組織的な活動の総称である)。レビューには、同僚などによるもの、上司や先輩などによる経営的な判断を含むもの、そして外部の専門家や他の部門の技術者の意見を聞くためのものなどがある。
ソフトウェア開発においては、ソースコードにもドキュメントにもバージョン番号をつけ、それがどの時点で作成されたものであるかがわかるようにしておかなければならない。変更に関するドキュメントも必ずレビューされなければならない。レビューの範囲がどれくらいになるかは、施された変更の程度による。
- 要求分析
ソフトウェア開発工程の第一歩は、顧客が何を要求しているかを記述することからはじまる。このドキュメントには、その顧客の要求に応えるために必要とされる機能がリストアップされていなければならない。このようにして作成される文書は要求仕様定義書と呼ばれる。要求仕様には、「どういったものを開発すべきか」、「どういったユーザがそれを使うのか」といった問いに対する答えが記述されていなければならない。
要求仕様定義書は、マーケティング部門と開発部門の協力による成果物でなければならない。失敗してしまうプロジェクトを見ると、この要求仕様書がまるで回覧か何かのようにマーケティング部門から開発部門にまわされるだけのことが多い。そして、それを受け取った開発部門は、物理学の法則を持ちだしたりして、要求仕様どおりの開発が難しいことを説明したりしている。そのように開発できないのは、クリプトナイトがすぐ入手できないとからだ、と言ったりしている。要求仕様をレビューするだけが技術者の仕事ではない。彼らも、そのかなりの部分を自ら書かなければならない。
- システム設計
これは、「モジュールレベルの設計」である。この工程では、各モジュール間のインターフェイスをかため、まず第一に、開発システム全体が正しく動作する感触を確実にする。第二に、開発に要する総工数を割り出す。
この工程では、文書を作成して、要求仕様定義書どおりのシステム設計が行なわれたかを検証する方法・手順を記述しておかなければならない。
- 詳細設計
この工程では、システム設計書にある個々のモジュールについて、詳細な設計を行なう。モジュール間のインターフェイス(コマンド呼び出し形式、API(Application Programming Interface)、外部データ構造)はこの段階で完全に決定されていなければならない。モジュール間の依存関係も決定されていなければならない。PERTチャートやGANTチャートもこの工程で作成し、モジュールごとの作業内容や手順、タイムテーブルを割り出しておく必要がある。
個々のモジュールの動作確認テストをどう行なうかについても、この段階で決定し、実装責任者が検証テスト用のデータを作成できるようにしておかなければならない。なお、検証テストでは、機能面とは無関係のテストを行なうこともあるが、これについては後述する。
- 実装
この工程では、詳細設計書の仕様にそって、各モジュールが実装される。つまり、各モジュールのソースコードが実際に作成され、ソフトウェア開発の中核となる作業が行なわれる。コーディングやプログラミングは、ソフトウェア工学の中で唯一効果的に独習できる部分であるが、はなはだ残念なことに、この部分だけをソフトウェア工学と教えこまれている人たちもいる。この部分だけをソフトウェア工学と思い込んでいる人たちもいる。
モジュールは、コーディング−コンパイル−デバッグ作業を繰り返しながら開発する。モジュールは、コーディングされ、テストされ、ほかのモジュールからちゃんと呼び出されることを確認された(ないしはシステムレベルでのテストにパスした)段階で、実装済みとなる。単体テストでは、詳細設計書にそって機能テストを行ない、リグレッションテスト(回帰試験)を行なう。性能テストやストレステスト、そしてカバリッジ(保証範囲)の分析なども行なわなければならない。
- 結合テスト
これは、すべてのモジュールが計画どおりに完成した段階で進む工程である。結合テストは、すべてのモジュールをコンパイルリンクし、ひとつのシステムとしてまとめる。この作業は、モジュールの実装作業と並行的に行なうともできるが、すべてのモジュールが実質的にでき上がるまでは、結合テストの工程が「完了した」とみなすことはできない。
なお、この工程には、システムレベルでの検証テストも含まれる。インストールについても、自動的に行なうようにするのであれば、単にtar(アーカイブ)されているものを解凍するだけのインストーラであっても、CD−ROMからファイルをコピーするだけのインストーラであっても、テスト用の環境(またはシステム)を作成して、実際に自動的に検証テストを行なえるようにする必要がある。
ミドルウェアの開発においては、異なるビルド番号(実行可能モジュールごとの作成履歴番号)のソースがいくつも含まれているものが最終成果物となりうる。そのような場合には、インストーラとして使えるようなものがないので、検証テストはビルドごとに行なわなければならない。
インストール可能なシステムが正しくインストールできたら、システムレベルでの自動検証テストを行ない、引数を可能な限りの組み合わせで使って、すべてのユーザに公開されているコマンドが適切に動作することを確認しなければならない。すべてのユーザに公開しているライブラリモジュールを適切に呼び出せることを確認しなければならない。開発システムにデータベース作成機能がある場合は、自動検証テストプログラムでデータベースを作成し、(別個に書かれた)外部ツールを使ってそのデータベースに欠陥がないことを確認しなければならない。単体テストをしっかり行なうことで、結合テストの一部を代行することもできるが、その場合は、結合作業、ビルド作業、パッケージング作業を通じて、継続的に単体テストを行なわなければならない。
- 総合テストおよび実地検証
この工程は、まずプロジェクト内部で行なわれる。つまり、開発グループのメンバー自体が、自分たちのマシン上でシステムを動作させてみるのがこの工程の第一ステップである。この動作テストは、最終的にはデスクトップ、ラップトップ、サーバなどといった、「実際に使われている様々なマシン上で」行なわなければならない。顧客に新しいソフトウェア(または現行ソフトウェアの新バージョン)を使ってみてほしいと依頼するとき、「自分たちで動作テストしました」と告げたいのである。開発グループ内で総合テストおよび実地検証を行なっている間は、それぞれの部分の開発担当者が直接技術サポートできる体制を整えておかなければならない。
総合テストおよび実地検証の最終段階では、ソフトウェアを外部で動作させる。つまり、顧客(または顧客になってくれそうな人)のコンピュータ上で動作させることになる。この場合、「協力的な人」を選ぶのが一番である。最初のうちは、ささいなことも含めて、いろいろな問題が見つかるからである。開発者とエンドユーザでは、システムの使い方が異なり、それによって様々な点が問題として浮上することも多いが、「協力的な人」であればその辺の事情を理解してもらえるはずである。総合テストおよび実地検証を外部で行なっている間は、それぞれの部分の開発担当者が近くで待機するようにしなければならない。
総合テストや実地検証で発見された問題は、シニアエンジニアやテクニカルマーケティングの担当者らが対応優先度を決定し、その順位にそって修正されなければならない。つまり、現バージョンをリリースする前に修正しなければならないものはどれか、次期バージョンで修正できる(あるいは修正不能な)ものはどれか、マニュアルの修正で対応可能なものはどれかを決定する必要がある。
- 保守
問題点は、総合テストや実地検証で見つかったものであれ、リリース後に見つかったものであれ、記録に残して、後日対応できるようにしておかなければならない。ソフトウェアの問題点は、保守作業を担当するグループに最終的には引き渡される。保守作業においては、システム定義が変更されることもある。詳細設計に変更が加えられる場合もある。あるいは、特定のモジュールの仕様や実装が変更されることもある。変更が施された場合は、単体テストや総合テストに新たな項目を追加し、その変更によって問題点が修正されたことを確認できるようにしなければならない。リグレッションテストにも新たなケースを追加し、同じ問題が再発する恐れがないことを確認できなければならない。
要求仕様定義の作成作業が開発部門とマーケティング部門の相互協力でなりたつように、ソフトウェアの保守作業は開発部門と顧客サポート部門の相互協力でなりたつものである。また、保守作業はバグレポートに基づいて行なわれるのが普通である。このレポートには、バグの種類、バグの説明、リリースバージョンに含まれる重大な問題の総数などを記録する。
テストの詳細
- カバリッジの分析
ここで言う分析とは、ソースコードに間違いがないことを調べ、確認する作業のことである。この作業は、プリプロセッサごとに行なうこともある。コンパイラやリンカを使って、オブジェクトコードモディファイアのカバリッジを調べることもある。ソースコードのどの部分が実際に実行されているかを記録できるツールを使って分析作業を進めることもある。
カバリッジ分析を行なう際の問題点を、次の例を使って少し具体的に検討してみよう。
1. if (read(s,buf, sizeof buf) == -1)
2. error++;
3. else
4. error = 0;
この例では、変数errorが初期化されていないと、一行目の実行結果が予期せぬ値となり、プログラムが正しく働かない。通常のテストでは、一行目のread関数での読み込みが失敗し、二行目が実行されるようなケースに遭遇することはまれである。単体テストの段階で、考えられる限りのケースを網羅的にテストし、この種のバグを取り除いておけば、多大な時間と費用のかかるバグ取り作業を後日行なわなくて済む。
しかし、話はそれほど単純ではない。というのも、コードは前後の関連性を持って実行されるからである。たとえば、前記のif節が下記のような文脈で使用され、一行目のシステム関数が正常に働いていれば、変数errorは四行目で初期化されるので、六行目のインクリメントの結果が予想外の値になることはない。このコードは、あまりにもひどすぎて、どんなレビューもパスしないことは明らかであるが、単純なケースがいとも簡単に複雑なケースに変貌してしまう例として紹介しておく。
1. if (connect(s, &sa, &sa_len) == -1)
2. error++;
3. else
4. error = 0;
5. if (read(s,buf, sizeof buf) == -1)
6. error++;
7. else
8. error = 0;
このコードを網羅的にテストするには、次の四つのケースについて調べなければならない。
1. 1行目-2行目-5行目-6行目
2. 1行目-2行目-5行目-8行目
3. 1行目-4行目-5行目-6行目
4. 1行目-4行目-5行目-8行目
可能な限りあらゆるケースを網羅的にテストすることは、普通とてもできない。数十行しかないような小さな関数でさえ、それを完全に網羅的にテストするとなると、何百のケースについて調べなければならないからである。しかも、単にプログラムを一行ずつ網羅的にテストしただけではカバリッジの分析をちゃんと行なったことにならない。つまり、現場のエンジニアは、カバリッジの分析を適切に行なう知識や技術を持ち合わせていない。だからこそ、品質保障部門があるのである。
- リグレッションテスト
「見ため明らか」という言葉は、「原因を究明するテストを書くのが難しい」ことを巧妙に隠す口実としてよく使われる。しかし、バグを修正しても、その後何もしないのでは不十分である。もちろん、(定数の)ゼロによる除算のように一見しただけで間違いとわかるようなバグもたくさんある。しかし、バグは、怪しそうな部分だけでなく、その前後を調べて、もともと何をするために書かれた部分であるかを突き止めてから修正にとりかかるのが普通である。この種の作業で明らかになった情報は、バグ取り作業の一環として修正報告書に記録するか、ソースコード内にコメントしておく必要がある。
一般的に、一見してわかるようなバグは少なく、プログラムの動作がおかしくなる箇所とはまったく別の箇所がバグっていて、プログラムがコアダンプしたりすることがある。そのような場合は、プログラムの動作がおかしくなる箇所ではない部分のソースコードをいじることになる。その際は、修正作業に入る前に、問題を再現できるデータや仕掛けを作成しておき、修正を行なった後、それを使ってリグレッションテストをしなければならない。そして、バグ取り作業が完了した時点で、作業内容をレビューし記録しておく。どのようなリグレッションテストを実行したかも記録しておくようにすれば、別のバグフィックスの副作用で同じバグが再現したとしても、品質保障部門が顧客より先に発見する可能性を高めることができる。
オープンソースの場合の工学的アプローチ
オープンソースプロジェクトでも、上述したソフトウェア工学的要素をこなす形で開発を行なうことができる。公正を期すために言えば、なかには確かにそうしているところもある。たとえば、商用版BSDや商用版BIND、そして商用版sendmailなどはどれも、通常のソフトウェア開発の工程をへて開発されているが、これらにしても、はじめからそういうふうに開発されていたわけではない。本格的なソフトウェアエンジニアリングは非常に多くのリソースを必要とする。それを実践するにはかなりの資金を必要とし、それゆえ、何らかの形で収益計画を持たなければならない。
オープンソースプロジェクトで一番多いのは、それに携わっている人たちが自分のやっていることを楽しんでいるというケースである。彼らは、自分が作ったものをできるだけ大勢の人に使ってもらいたいとの思いから、ソフトウェアをただで配ることが多い。再配布時の制限もつけないことが多い。こういった人たちは、往々にして、いわゆる「商品として出回っているソフトウェア開発ツール」を使える環境にいない(たとえば、コードカバリッジアナライザ(code coverage analyzer)、バウンズチェッキングインタープリタ(bounds-checking interpreter)、メモリインテグリティベリファイア(memory integrity verifirer)などを使える環境で開発作業をしていない)。彼らは、コーディングやパッケージ化は喜んでする。ソフトウェアのよさを説いてまわることも喜んでする。しかし、品質管理や要求仕様のまとめをちゃんとすることとか、開発スケジュールを厳守することにはあまり関心がない。
以下では、ソフトウェア開発の工学的アプローチに含まれる工程をもう一度取り上げ、開発資金を持たぬオープンソースプロジェクト、つまり「ボランティアでする仕事」において、どんなことが実際に行なわれているかを考察してみよう。
- 要求分析
オープンソースプロジェクトに携わる人たちは、必要なツールや、こういうものがほしいと思うものを自分で作る傾向がある。よくあるのは、仕事をしていてそれが必要になったので、自分で作ったというケースである。そして、そのような場合、開発者の専門は、ソフトウェア開発そのものというよりは、システム管理だったりすることが多い。そういう人たちが、何度か試行錯誤を繰り返して作りこんだものをインターネットを通じて配布する。するとそのソフトウェアが一人歩きをはじめ、仕様を拡張してほしいと要望してくるユーザが現われたりする。自分で機能を実装して、そのプログラムのソースコードをメールしてきたりする人もいる。
オープンソースプロジェクトの場合、要求仕様は、メーリングリストやニュースグループでのやりとりを通じて決まっていく。このやりとりの中で開発者が記憶していることや、開発者が同意したことが、仕様として実際に取り上げられる。この形での解決に納得がいかない人たちがでてきた場合には、意見を異にするグループがそれぞれに独自の方向に進み始める。その結果、ソースコードとして複数のバージョンが出回るようになったりする。オープンソースプロジェクトにおいて、要求仕様に相当するものを練り上げていくことは非常に実のある作業であるが、仲間内で論争が起こってしまうと、話し合いによる解決が不可能になることもある(場合によっては、解決を試みようとしないことさえある)。
- システム設計
開発資金に乏しいオープンソースプロジェクトでは、システム設計を行なうための工程というものが存在しないのが一般的である。システム設計書は、暗黙の了解のもとに、はじめから絶対的なものとして、開発者の頭の中に完全無欠な形で存在しているか、開発されるソフトウェアと同様、時間の経過とともに発展的に形成されるかのいずれかである。とはいえ、オープンソースであっても、バージョン2とか3ごろまでとなると、文書化されていないかもしれないが、システム設計書に相当するものが存在するのが一般的である。
オープンソースプロジェクトでは、ソフトウェア開発の工程が通常の実践形態から逸脱している点がいくつかあるが、オープンソースが当てにならない理由としてよく指摘されるのが、システム設計工程の欠如である。正式な要求仕様定義書などなくても、またソフトウェアの品質管理を型どおりに実行しなかったとしても、優秀なプログラマ(あるいはきわめて協力的なユーザ)がいれば、埋め合わせはつく。しかし、システム設計書が誰かの頭の中にすら存在しないプロジェクトがあるとすれば、そこで開発されるソフトウェアの品質は推して知るべし、となってしまう。
- 詳細設計
開発資金に乏しく、楽しみでやっているプロジェクトでは、詳細設計の工程も実践されないことが多い。詳細設計が好きで楽しみという人もなかにはいるが、そういう人は勤務時間中に仕事として楽しみながらそれをしている。オープンソースでは、詳細設計が往々にして、実装時の副産物として行なわれるケースが多い。「パーサが必要なことがわかったので、その仕様をひとつ書こう」といった具合である。APIを作成したとき、その仕様の詳細をヘッダーファイルやオンラインマニュアルに記述しておくこともできる。しかし、そのAPIを公開しようとか、プロジェクトの関係者以外の人に使ってもらおうとか考えない限り、仕様を書き留めておこうと思う人はあまりいない。
これは非常に残念なことである。詳細設計書がなかったり、仕様が説明されていないソースコードは、いろいろ使い道があっても、結局使われずじまいになってしまうことが多いからである。再利用できないと思われるようなモジュールや、現在それを使用しているプロジェクト以外での利用方法がないようなモジュール、特に提供を約束しているわけでもないAPI、こういったものについても、その仕様や呼び出し方法についてはオンラインマニュアルなどで説明しておくべきである。そういうドキュメントが存在すれば、モジュールやAPIを改良したい人が、作業に着手する前にそれを読んで、ソースコードの内容を知ることができるので、非常に有効である。
- 実装
プログラマは、ソースコードを作成し、ソフトウェア開発の中核となる部分の作業を好んで行なう傾向がある。寝る時間も惜しんで、夜遅くまでコーディングに熱中するプログラマがいるのはこのためである。オープンソースの開発に多くのプログラマが参加し協力しようとするのも、コードを書く機会がそこにあるからである。ソフトウェア開発には様々な工程があるが、こと表現の自由を発揮できるチャンスは、実装工程に一番あると言える
オープンソースプロジェクトは、プログラマたちが新しいスタイルを実験する場でもある。ソースコードをどんなレイアウトで記述するかを実験的に試すプログラマがいるかと思えば、変数に使う名前をあれこれ試すプログラマもいる。「メモリを節約する方法」や「CPUサイクルを節約する方法」をいろいろ試すプログラマもいる。実際の話、オープンソースでは、誰かが実装した新しい試みがちゃんと機能しているソフトウェアに巡り会える機会がいたるところにある。
オープンソースプロジェクトも、厳密かつ一貫性を持って進めることができる。たとえそうできなかったとしても、機能性のあるソースコードを提供できさえすれば、ユーザはそれを使う。多くのユーザが気にするのは、ソースコードの機能性であって、記述スタイルが実装過程で何度変更されたかではない。しかし、開発者は一般的に記述スタイルを気にする。今は気にしていない人でも、だんだん気にするようになるのが普通だ。その意味で、ラリー・ウォールがかつて言った、プログラミングはひとつの芸術的表現だ、という言葉は当を得ている。
レビューについて言えば、オープンソース方式での開発では、フォーマルな形で行なわれることはない。同僚などによるレビュー、上司や先輩などによるレビューも普通はない。単体テストもないのが普通であり、リグレッションテストとか、そのほかのテストもないのが普通である。
- 結合テスト
オープンソースプロジェクトの場合、この工程は普通オンラインマニュアルを書くことからはじまる。そして、手持ちのすべてのマシン上で動作確認がなされ、メイクファイル(Makefile)が清書され、READMEが書かれ、システムがアーカイブされ、それがどこかの匿名ftpサイトにアップされる。そのうえで、開発者が、メーリングリストやニュースグループ上で、オープンソースのソフトウェアが新しくアップされたことを告知する。
ニュースグループと言えば、comp.sources.unixは、一九九八年にロブ・ブラウン(Rob Braun)の手によって再び活況を呈するようになっているが、ここはオープンソースの新しいソフトウェアや最新版について告知するのにもってこいの場所である。ソフトウェアのアーカイブサイトとしても機能している。
オープンソースプロジェクトでは、単体テストや結合テストの実施は計画に含まれないのが普通である。したがって、お察しのとおり、結合テストを行なう工程は存在しない。全般的に言ってオープンソース方式の開発では、テストの実施にあまり重きが置かれていない(もちろん、PerlやPostgreSQLなどの例外はある)。しかし、リリース前にテストをしないことがオープンソースプロジェクトの弱点というわけではない。その理由について以下で述べるので、次に読み進んでいただきたい。
- 総合テストおよび実地検証
宇宙に送るロボットに対してNASAが実施しているテストを除けば、オープンソースは、業界内で最高水準のテストを受けている。ユーザはお金をとらなければ、いろいろ協力的な情報を寄せてくれる。自身が開発者であることが多いパワーユーザも、ソースコードに自分でアクセスできて、バグフィックスが自分でできるときは、いろいろ力になってくれる。
実地検証で不可欠なのはバリエーションである。開発者の立場からすると、ソフトウェアの作成時点で、すべての使用パターンが予測できるわけではない。したがって、実地テストをする人たちから開発者が入手したいのは、その人たちの使用パターンである。言い換えれば、開発側は、現実のエンドユーザがどんな経験をしているかを知りたいのである。この種の情報収集に関する限り、オープンソースプロジェクトは誰にも負けない。
オープンソースのユーザは、ただ単に実行ファイルを使うだけではない。彼らは、ソースコードにも目を通す。これが、オープンソースプロジェクトの強みのひとつである。オープンソースでは、何十、何百というプログラマたちがシステムをレビューし、ソースコードを読んでバグを探してくれる。もちろん、セキュリティ上の欠陥を探そうとしてソースコードを読む人もいる(クラッカーでなくても、こういうことをする人はいる)。発見されたセキュリティホールが報告されないこともある。しかし、そのような危険はさておいても、オープンソースには、見も知らぬ無数の人たちの多くの目によってソースコードがチェックされるというメリットがある。このような見も知らぬ目を意識するからこそ、オープンソースの開発者は慎重にプログラミングするようになる。上司や先輩がいくら口酸っぱく指導してもなかなかそううまくはいかない。
- 保守
エンドユーザは、バグを発見すれば、「なんだぁー!」という言葉を口にする。そして、改訂版が送られてくれば、「おっと、やれやれ、これで助かった」などと言う。オープンソースのバグ対応の典型を一言で表現すると、「試してみたところ、これが動作しましたので」となる。それでは対応が混乱していて、秩序がないと思われるかもしれないが、事実そうなのである。サポートの欠如を指摘して、オープンソースのプログラムを使わない人もいるし、実際問題として使えない人もいる。しかし、オープンソースのコンサルタントという商売がはじめられるのも、こういう状態だからこそである。オープンソースのサポートをビジネスにできたり、オープンソースをもとに商用バージョンを作成できたりするのも、オープンソースのサポートが欠如しているからこそである。
UNIXベンダーが、市販パッケージにオープンソースのソフトウェアを含めてほしい、というユーザからの要望を聞き入れることにしたとき、彼らは「わかりました、やりましょう。でも、サポートはいたしません」と言っていた。その後、シグナスソリューションズ社などがユーザサポートのビジネスで大成功を収めたことから、そうした姿勢を改めようとする気運も芽生え始めてはいるが、オープンソースのソフトウェアをどうサポートするかについては根源的な見解の相違が相当ある。オープンソースのサポートを計画したり、その費用を予算化したりすることは、そのソースコードを無数のユーザがレビューなしに変更できることを考えると、UNIXベンダーを含めた従来型のソフトウェアハウスにとってはできない相談なのである。
しかし、ソフトウェアハウスがオープンソースのソフトウェアのサポートをする方法がないわけではない。オープンソースのソフトウェアを自社用にしてしまい、それに対して通常のテストやサポートを行なう手もある。その際、実際に機能テストなどを行なう品質保障部門に対しては、リバースエンジニアリング手法で作成した要求仕様書や詳細仕様書を手渡すこともできる。サポート契約書の文言を「結果を保証する」ではなく「最大限努力する」に書き換える、という方法も考えられる。いずれにしても、オープンソースのソフトウェアのサポート市場は、最終的には、無数の見知らぬ人たちを協力者として取り込める企業によって占められることだろう。なぜかというと、そういう人たちの多くはすでに優れた技術者として優れたソフトウェアを作成しているからである。オープンソースのコミュニティは、ユーザが本当にほしがっている機能を実現しようとするときに、もっとも力強さを発揮するからである(Linuxとウィンドウズを比較しても、この点は明らかである)。
結論
エンジニアリングは古くから実践されてきた分野である。そして、作るものがソフトウェアであれハードウェアであれ、あるいは鉄橋であれ、開発工程に含まれる工学的要素は根本的に一緒である。
- 誰がどのような要求を出しているかを分析し明らかにする。
- その要求分析の結果を満足し、ソリューションを提供しうるシステムを設計する。
- その設計内容をモジュール化し、実装計画を立てる。
- システムを構築し、テストし、配布し、保守する。
ただし、分野によって、重点を置く工程に差がでる。鉄橋の建設においては、要求定義や実装、あるいは保守について考慮する必要はそれほどない。しかし、システムレベルの設計や詳細設計は細心の注意を払って行なわなければならない。もちろん品質保障も慎重に実施しなければならない。
「プログラマ」が「ソフトウェアエンジニア」へと変身する重要な転換点とは、本人がエンジジアリングという分野の存在に気づいたときである。そして、やるべき仕事がたくさんあり、自分のものの見方も根本的に変えなければならないと悟ったとき、「プログラマ」は「ソフトウェアエンジニア」になれる。オープンソースの開発者のなかには、何年か活躍した後で、はじめてプログラミングとソフトウェア工学の違いに気づく人が多い。それは、オープンソースの場合、ソフトウェア工学を厳しく実践しないゆえの苦境を味わうまでに時間がかかるからである。
ソフトウェア開発に含まれる工程についてごく簡単に述べたが、これを読んでオープンソースのプログラマたちがソフトウェア工学の分野に参入してくれることを期待したい。未来はつねに過去および現在に起こった最善のものの混合体である。ソフトウェア工学は、高品質のシステムを構築するために有効とされる多くの技術を提供できる分野である。しかも、オープンソースプロジェクトでよく見られるような、「一人の有能なプログラマ」のアプローチでは生みだせないシステムを構築するのに適した技術を提供できる分野なのである。