Home日記コラム書評HintsLinks自己紹介
 

フィンローダのあっぱれご意見番 第116回「要求外仕様」

← 前のをみる | 「フィンローダのあっぱれご意見番」一覧 | 次のをみる →

2001年9月19日、 東京都の文書管理システムを日立製作所が750円で落札したそうだ。 実はこのニュースを知ったのは9月ではなくて、 11月に公正取引委員会が警告を出した時なのだが、 1円入札とか10円入札というニュースが過去に何度もあったせいか、 それまで気付かなかったのかもしれない。

という感じで考えてみると、 750円というのは随分中途半端な金額で、かえって意味がよく分からない。 報道で垣間見た感じでは、 このソフトウェアは既製品を使うために開発費がかからないという。 だったら0円ではないかと思うのだが、納入価格は9万円と試算して、 1か月の使用料が750円ということらしい。 つまり、9万円を750円で割ると120である。

日本のソフトウェア技術に関しては緒論あるが、 10年間そのまま使い続けることが可能なソフトウェアを手駒に持っているとは、 日立製作所のソフトウェア技術も侮れないものだ。 何のバージョンアップもなしに10年後も実用に耐えるソフトを作れるメーカーは、 世界中捜しても他にないのではないか。

まさか、1年後に「最新版は10億円ですが、 バージョンアップ版は登録ユーザに限り4億円です、どうしますか」 のようなふざけたことを言い出したりはしないと思うけど。

§

ソフトウェアに限らず、 入札方式の最も大きな問題は、 ある必要最低限の条件を満たせば、 あとは見積もりが安い側が無条件に勝ってしまうということである。

最低限の条件を満たしたモノを作れば全て同じ品質になるかというと、 まずそんなことはない。 実際は、業者によって品質が違うのが普通である。 きっちり仕上げる業者もあれば、 他社以上に気合を入れて作る業者もあるだろう。 あるいは、 手を抜いて作ったとか、杜撰な仕上がりだとか、 ある程度の専門知識があればあり得ないような工事だったとか、 残念ながらそのような事件もある位だ。 もっとも、手抜きするためには高度な技術が必要なのかもしれないのだが。

  

特にソフトウェアには、品質差が非常に大きくなることがある。 品質を保証できるソフトウェアを開発するためのパラダイムが長年にわたって考えられてきたし、 今でも考えられているのだが、 それでも開発チームとかプログラマーによる品質差は歴然として存在する。 皆さんも 「新バージョンは処理速度が3倍になりました」 というような宣伝を見たことがあると思うが、 お客さんもそれを聞いて「おお、凄い技術力だ」と勘違い(?)する。 もちろん、勘違いでなく、まさに画期的な技術に目覚めた結果であるのかもしれないし、 非常な努力の賜物かもしれない。 しかし、現実にありそうなのは、 最初のバージョンでは、 本来できるはずの能力の1/3しか出せないソフトになってしまったという話だろう。 なぜそうなるかというと、 多分これも勘だが、最も大きなファクターは「納期」なのだ。 締め切りに間に合わせるために、とりあえず動くものを作ろう、というのも常套手段である。 最適化はそれからの話になってしまうのだ。

 

※ 実際は 1/3 ではなく 1/100 だったりすることもありそうな気がする。

信じられないかもしれないが、 場合によっては、パフォーマンスが100倍違うことも珍しくない。 さらに極端な場合だと、それ以前の問題ということで、 「動かない」とか「使用中に異常終了する」という事態になる。 こうなると、もはや要求仕様を満たしているかどうかも怪しいのだが。

§

ソフトウェアの場合、要求仕様として応答性能が問題になることがある。 1つの処理が1秒以内に完了すること、とか、 1分あたり何万トランザクションを処理できるとか、 そのような数値的な要求を満たさなければならない。

「アクセスが殺到したためにサーバが停止した」 というようなニュースを見たことがあるだろう。 実はそうでもないのかもしれないが、 おそらく、このサーバは要求仕様通りに作られているのだと思う。 1日に100万ページビューの処理が要求されたら、 それを保証するサーバを納品するのは当然として、 そこに200万ページビューに相当するアクセスが殺到したら、 そりゃおかしいことになるだろう。 設計時に想定したアクセスを上回ったら、処理できないのだから、 ある意味、異常が発生するのはやむを得ないのだが、 本来はそのような場合にどうなるかも事前に決めておくべきなのかもしれない。 ちなみに、アクセスが殺到するサイトといえば、 本家Yahooが1日あたり数億ページビュー、 Yahoo Japan だと数千万ページビュー、 あるいはもう少し増えているかもしれないが、その程度だと言われている。

ただ、このサーバが1日100万ページビューを保証するといっても、 101万ページビューに耐えられないのかというと、そういうことはまずない。 スペック通りに設計できることは稀な話で、 100万ページビューを満たすように作れば、多少の誤差が入って、 例えば計算上は121万ページビューまでokだとか、133.4万まで大丈夫とか、そういう話になるはずである。

もしかすると、このシステムのサーバを入札した時、 少し高い価格を提示したために落札できなかったB社のシステムが、 実は300万ページビューにも耐えるようなスペックだったかもしれない。 100万ページビューという要求仕様に比べると、 明らかにこれはオーバースペックなのだが、 ソフトウェアの性質として、2倍や3倍の性能差は簡単に発生するのである。 一般論として、1秒以内のレスポンスが要求されたのに、 実際に作ったら0.1秒以内に応答してしまったというような場合、 大幅なコストダウンが見込める場合でもなければ、 わざわざ要求仕様の値になるように性能を削るようなことはしないものだ。

あるいは、実はA社よりも少し高い価格のC社のシステムにしておけば、 ページビューの限界値は似たようなものだが、 実はアクセスが殺到した場合のエラー処理に工夫があって、 システムそのものは正常に動作したのかもしれない。 さらには、もしD社のシステムにしておけば、 異常事態が発生してシステムダウンしても、 A社のシステムだと2時間かかる再起動処理が、 10分で正常な状態に戻せたかもしれない。 この種の仕様は要求されない限り仕様書には出てこないのである。

そもそも、システムダウンした時にどうするという設定が異常であって、 その時にどうなるかということまであらかじめ想定するかどうか怪しいものである。 もっとも、現状から考えると、 システムダウンは当たり前ということで想定した仕様書があってもおかしくはないと思うが。 どう考えても、要求仕様の範囲外の状況になった時にどうするかという話は、 もちろん要求仕様とは関係ないのだ。 結局、入札時の価格差に対して、品質とか性能を考えると、 価格差以上のメリットが見出されるような場合、どうすればよいかという問題なのか。 ページビューの性能のような数値で比較できるものはまだよいが、 画面デザインのようなユーザビリティから嗜好に及ぶような要素はどうやって比較すればいいだろう? こっちのデザインの方が好みだけど、見積もりが高い、というような場合。

§

密かにVC++を勉強している最中なのだが、ある本に次のような記述があった。

---- List 1 ----

    m_nColor = ID_COLOR_BLACK - ID_COLOR_BLACK;

---- List 1 end ----

m_nColor を初期化する処理に出てくるコードである。 ID_COLOR_BLACKはプログラマーが定義したIDで、 BLACKから順に色を表現する8種類が割り当てられているのだが、 それらのIDが実際にどのような値に割り当てられるかは、 ここをコーディングしている時には分からない。 100になるかもしれないし、32768かもしれない。 そのこと自体は別に問題ないのだが、 内部処理の都合としては、8色のカラーに対するパレットテーブルを持ちたいから、 それらのIDを0から7までの整数値にマッピングしておきたい。 そこで、m_nColor というメンバ変数に、 0から7までの値を突っ込むという仕様になっているのである。 蛇足かもしれないが、それ自体分かりにくい話で、 だったら最初から色に対応したIDを0から7にすればよさそうなものだが、 システムの都合でそういう訳にいかないのだろう。 あるいは、私のスキルがまだそこまで到達していないだけなのかもしれないが。

それはさておき、 問題はもう一つある。 つまり、なぜ0で初期化しないのか。 ここでどうもひっかかってしまったのだ。 AからAを引いたら0になる、というのは分かりきったことだ。 ならば、List 2 のように書けばいいじゃないか?

---- List 2 ----

    m_nColor = 0;

---- List 2 end ----

どう見ても、List 2 の方が分かりやすいような気がするが、 あえてList 1のように書いたということは、何かしらの理由がある筈だ。 それが分からないのである。

BLACKで初期化するというアピールなのかもしれない。 しかし、もしそうなら、私としてはList 3 のように書きたい。

---- List 3 ----

#define ID_COLOR_OFFSET ID_COLOR_BLACK

    m_nColor = ID_COLOR_BLACK - ID_COLOR_OFFSET;

---- List 3 end ----

これなら、仮にその値が0になるのだとしても、 この引き算を書く理由はあると思う。 ID_COLOR_BLACKがたまたま最も小さい値だということと、 OFFSET からの距離を値としてセットするのだというのは、 思想が違うのである。 手間がかかることをしても、その効果がなかったら意味はない。 List 1 が無意味だとは言わないが、 プログラマーの意図が伝わるかどうかは怪しいと思う。

もっとも、このプログラムだが、初期化はともかくとして、 ビルド後に実行させたら落ちてしまった。 デバッガはm_nColorにものすごくヘンな値が入っていると教えてくれるが、 なぜそんな値が入ってしまったのか分からない。 まだまだ修行が足りない。

  

(C MAGAZINE 2002年2月号掲載)
内容は雑誌に掲載されたものと異なることがあります。

修正情報:
2006-03-03 裏ページに転載。

(C) Phinloda 2002-2006, All rights reserved.