2009-03-04

ソフトウェア開発における暗黒面の誘惑

西洋の真似をするだけというのはそろそろやめよう』の記事に ssw さんから以下のようなコメントをもらった。
初めまして。共感する記事だったので、サムライエンジニアの話も読んでみました。
仰る武士道エンジニアは、私の知る限り多くの場所にいました。しかし、成果を上げる能力を持った誠実なエンジニアほど、業界を去る例が多いように思っています。いくら注意してもバグやトラブルで切腹を余儀なくされる侍に重なって見えないでしょうか?

私も侍エンジニアを目指したいと思いますが、SW風に言う暗黒面の誘惑を断ち切れず、過剰防衛や飛び道具を捨てられません。もうちょっと修行が必要なようです。

面白い記事ありがとうございました。

sswさんの言う「暗黒面の誘惑」はソフトウェアの世界では特に多いように思うので、今回はソフトウェア開発における暗黒面の誘惑について考えてみたい。

ソフトウェア開発は「見えない」とよく言われる。だから「ソフトウェアの見える化」が大事であるとよく言われる。ソフトウェア開発が外から見えない状態ではソフトウェア開発における暗黒面の誘惑を減らすことはできないが、ソフトウェア開発を見えるようにしただけでは暗黒面の誘惑を断ち切ることはできない。

本題に入るまえに、ソフトウェアが原因となった事故とその事故を詳細に調査したナンシー・レブソン教授(現 MIT教授)のことばを見て欲しい。

【放射線治療器 Therac-25 の事故】

1985年~1987年 セラック25による事故。複数の医療機関で放射線治療装置が誤動作し、過大な放射線を浴びた患者に死傷者(6名)がでた。この事故はソフトウェアの不具合が原因であり、見えないソフトウェアのせいで再発防止が進まない中、ナンシー・レブソンらの努力により事故原因が詳細に調査され、レポートが発表された。このレポートは20年以上たった今でも、ソフトウェアエンジニアにとって深い教訓として伝えられている。

英文ではあるが次のアドレスからレポートを読むことはできる。

ここでは、事故を調査したナンシー・レブソン教授のいくつかのことばを見ていただきたい。
  • どんなに慎重に作ってもソフトウェアは満足できるほどに完璧にはならないため、ソフトウェアがどんな動きをしたときでも、人命に危険が及ばないようにシステムを設計する必要がある。
  • ソフトウェアの信頼性をできるだけ高めるのは悪いことではないが、それでソフトウェアが安全になるわけではない。プログラマは要求を満たすようにコードを書くが、要求が正しいとは限らない。事故のほとんどは、プログラミングのエラーではなく、要求が間違っていたり、不完全であったりしたために起きている
  • われわれの目標は、だれもがこの経験を生かせるようにすることであり、装置のメーカーや他の人を批判することではない。間違いは、このメーカーにだけ起きたのではなく、残念ながら、安全が最優先されるべきその他のシステムにも、きわめて日常的に起きている。
  • いくつかの出来事が複雑に絡み合って起きた事故が、一つの原因にされることが多すぎる。ほとんどの事故は、システム事故、つまり、さまざまな構成部分や機能が複雑に作用しあって起きるものだ。事故の原因を一つに特定することは、大きな間違いだ。
これらをことばを聞いて思うのは、Therac-25 の事故から20年以上たった現在でもソフトウェアに関する問題は何も変わっていない。20年間の間進化したであろうソフトウェアシステム、ソフトウェア開発の方法論はソフトウェアに起因するこのような危険を回避できていないということだ。20年間技術が何も進化していないのはない。いろいろな技法、手法を使ってソフトウェアを作るのは人間であり、ソフトウェアの設計は人間が行っているのであり、安全なソフトウェアはナンシー・レブソン教授が事故調査で痛感した教訓を技術者が十分に理解し、意識し、設計の規範を組織が先輩が後輩に伝承させなければいけないことを20年もたっているのに多くの人が理解していないということである。方法論が先行して、目的が忘れ去られ、結果的にソフトウェアを作っているのが人間であるということが置いて行かれてる。

ナンシー・レブソン教授が残した「いくつかの出来事が複雑に絡み合って起きた事故が、一つの原因にされることが多すぎる。ほとんどの事故は、システム事故、つまり、さまざまな構成部分や機能が複雑に作用しあって起きるものだ。事故の原因を一つに特定することは、大きな間違いだ。」ということばについて考えてみよう。

ソフトウェアに関する問題が起こったときの分析者の問題分析の仕方、分析能力の低さに愕然とすることがある。一番多いどうしようもない指摘の仕方は、ソフトウェアにおける問題が発生したときに、原因を一通り担当技術者に説明させ「そのプログラムは一体誰が作ったのだ」と問いただし、問題の原因をそのプログラマの「うっかりミス」ということで帰結してしまうケースだ。

「プログラマのコーディングミス」。この原因ほど結論づけるのが簡単なものはなく、「プログラマのコーディングミス」が問題の原因であると結論づけるような組織は Therac-25 のような事故を起こす可能性が高い。

「プログラマのコーディングミス」を問題の原因とするのは、問題の分析者がソフトウェア開発の十分な経験を持っていないからだろう。ソフトウェアのことはよく分からないから、誰かのせいにしてしまうのが一番簡単なのだ。品質保証担当は問題の原因を特定し、再発防止策を指示する責務を持つ。だから、ソフトウェア開発の経験を持たず、品質保証についてスキルを高めることを怠っているQA担当は、問題が起こると、原因を聞いても内容がよく分からないから、誰がバグを作り込んだのかを特定し、そのプログラマに何かしらの教育を行うことで再発防止策としようとする。

ナンシー・レブソン教授が言う「事故の原因を一つに特定することは、大きな間違いだ。」を思いっきりやってしまっている。

かなり昔のことだが、ソフトウェアに関する問題が起こったとき原因が「境界値テストが十分でなかった」という報告が現場から上がってきたことがあった。「プログラマのコーディングミス」となっていないだけよいと思うが、「境界値テストを行っているかどうかを水平展開しチェックしろ」というおふれが回ってきた。

「チェックしろ」というのは「うちは境界値テストはやっているのか」という問いに対して「・・・はい、たぶんやっていると思います」という答えでもよしとしてしまうレベルのチェックである。当時、この話しを聞いたときに、組織の上位層はいかにソフトウェアのことをブラックボックスとして見ているのか、ソフトウェアの品質を評価する客観的な指標を持っていないと思った。

境界値テストというのは、システムやサブシステムやソフトウェアユニット(関数やクラス)に対する入力に範囲があったときに、その範囲の最大値や最小値、範囲の外側の入力を与え、期待通りになるかどうかをテストすることだ。

しかし、システムレベルでの入力に比べて、ソフトウェアユニットレベルでの入力値は非常に多いし、入力に対して同じ出力がでるとは限らない場合もある。入力に対して同じ出力がでないのは、外部の関数とグローバルな変数を共有している(外部結合:External coupling または、共有結合:Common coupling) ようなことがあるからだ。組込みソフトウェアの場合、外部の状況をセンシングして、センシングした内容によって、システムの振る舞いを変えることがあるから、出力値が入力データだけで決まるデータ結合になっていない関数やモジュールが少なからずあるのだ。

仮に、データ結合(Data coupling)だけの関係を持つ関数 1000個で構成されるソフトウェアシステムがあったとしよう。1000個の関数に引数がそれぞれ3つずつあったとする。関数一つに対する入力値の境界値テストは最低でも6のテストケースが必要だ。したがって、すべての関数に境界値テストをすると6000のテストケースが必要となる。

「うちは境界値テストはやっているのか」と聞かれたら、「今回開発しているソフトウェアシステムの関数は現在1000であり、それぞれの関数の引数の合計は3000で、各引数に対して取り得る範囲の最大値と最小値の入力テストを実施しています。」と答えるのが回答例となるが、この答えもこのシステムの安全性や信頼性が高いかどうかの根拠として完全ではないと、ベテランのソフトウェア技術者の方なら感じると思う。

そもそも、境界値テストが不十分で問題が起こったのであれば、プロジェクトに対しては「うちは境界値テストはやっているのか」などというミクロな質問をするのではなく、「うちのソフトウェア開発における安全性や信頼性の評価指標は何か?」と聞いた方がいい。この質問に明確に答えられないプロジェクトは、「どうなればソフトウェア品質が確保されている」をいう評価指標を持っていないということだから、日程のプレッシャーに負けて、問題が残ったままのソフトウェアをリリースしてしまう危険性が高い。
※さらっと「ソフトウェア開発における安全性や信頼性の評価指標」を持っていないといけない書いたが、実はその評価指標を確立することは簡単なことではない。評価指標を確立することは非常に難しいし簡単な指標にしてもキチンとできてることを内外に示すのにどんなに苦労することか・・・
もちろん、完璧なソフトウェアを作るために検証を続けていたら、時間がいくらあっても足りないから、どこかでベースラインを切る必要はある。しかし、どこでベースラインを切るか、どうなったら品質が確保されたと言えるのかという評価指標はあらかじめ開発の上流で決めておかなければいけない。

だから、「うちは境界値テストはやっているのか」と聞くのではなく「今回の問題を考えたときに、うちのソフトウェアの開発計画における品質の評価指標を見直す必要はないか?」と問うべきなのだ。

上がこんな感じだと、下は「何か問題が起こっても簡単にごまかせる」と思ってしまう。これが、ソフトウェア開発における暗黒面の誘惑だ。「上はどうせソフトウェアのことなんかこれっぽっちも分かっちゃいないから、適当な理由をつけていい訳しておけば、この場の辛い立場を逃れることができる」と考えてしまう。

「ソフトウェア開発における暗黒面の誘惑」の結果、もっとも悪い台詞はクライアントサイドの場合は「それは○○外注さんのミスです。」「○○外注さんにはきつく言っておきます。」であり、サプライヤーサイドの場合「あんなに納品を急がされたらミスもするよな。」といったものではないだろうか。クライアントサイドの台詞は自分達の問題として受け止めずに、サプライヤーに問題の責任を先送りして、根本的な再発防止策を取っていないから罪は重い。

「ソフトウェア開発における暗黒面の誘惑」をなくすことが難しい理由は、ソフトウェアに関連する問題やその原因、責任をごまかすことが簡単だからだと自分は考えている。

「ソフトウェア開発における暗黒面の誘惑」を断ち切るため是非、次のことを考えて欲しい。

【ソフトウェア開発における暗黒面の誘惑を断ち切る方策】
  • 不具合や問題が発生したら正面から向き合い、プロジェクトとして再発を防止するための方策を関係者全員で深く掘り下げて考える。(個人の責任にしない)
  • 再発防止策(設計の規範)はプロジェクトが始まる前にメンバ全員で確認し、規範に対する逸脱が見つかったら注意を促す。
  • 誰のために、何のためにソフトウェアを作っているのか日々考えておく。
  • ソフトウェアの開発フェーズによって気持ちを切り替える。集中的なテストを実施した後、リリース後のソフトウェアの変更に対する責任の重さはとても重いことを忘れない。
「あたたかい人間関係の中のやさしい一員」の日本人には苦手かもしれないが、ソフトウェア開発における暗黒面の誘惑を断ち切るためには、プロジェクトリーダーの「品質を気にする意識」に関するリーダシップが不可欠であることがお分かりいただけると思う。

ここ何回かの記事を読んでいただければお分かりかと思うが、日本のソフトウェア開発はシステムと職人気質の両立が必須の世界であり、どちらかだけに偏っていては大規模、複雑化するソフトウェアを高品質に保つことはできない。ソフトウェアの品質の高さを維持することができなければ、日本の組込み機器は世界で生き残ることはできない。

ソフトウェア開発は「見えない」ことの問題よりも、ソフトウェアの安全性や信頼性について「自分はよく分からない=見ない、見たくない」とあきらめ、「問題を理解して確信を持って判断すること、責任を取ること」を放棄する人間がたくさんいることの方が本質的な問題であると思う。ソフトウェア開発における暗黒面の誘惑に負けると、暗黒の力に支配されてしまっていることさえ忘れてしまうから怖い。
 

0 件のコメント: