3.失敗に学ぶ
不可解な引力
賢い開発言語があっても、優れた管理手法があっても、抜きん出たスペシャリストがいても、それだけではなかなか上手くいかない、それがソフトウェアの世界。我々はしばしばソフトウェアの現場で不可解な引力で判断を誤ってしまう。なぜそんなものが存在するのか考えてみよう。
プロジェクトの分割
そこそこの規模の開発プロジェクトでは、複数のベンダーがサブシステムやコンポーネントごとに分割して並行に開発するケースが少なくない。この場合、それぞれが依存するシステムの要素が論理的な疎結合の状態であれば仕事が進めやすく良好な結果を得られやすい。逆にそれぞれが相互に依存していたり、論理的に密結合の状態になっていたりすると分割は命取りになるといっていい。
長年設計・開発をしているエンジニアは設計の概要を見ると、どの部分とどの部分が密、どこが疎であるか経験的・感覚的に鼻がきくようになる。そして、それは多くの場合実際その通りなのだ。そして、部分部分を適切な開発スキルを持ったチームへとそれぞれ引き渡し仕事が始まる。この判断基準は様々である。
- ドメイン
業務サイドの要件に着目することにより論理的な境界線を設ける場合、業務ドメインの知識がその基準となる。業務システムでは仕事の流れで機能がグループ化されるため、たとえば顧客管理、販売管理、財務管理などのくくりでシステムを分割することが出来る。開発にあたってはデータフローなどを駆使して業務の関連をよく把握した上で順序整理、分割単位の整理をする。
- 階層
分かりやすい例としては、ネットワークの階層図がある。役割を下位から上位までいくつかの層に分けて機能を定義する。各階層での機能と階層間のインターフェースを明確に定義することで分割した開発が可能になる。
- プラットフォーム
いくつかのコンポーネントで構成されるシステムでは、複数のプラットフォームに跨った開発を行うことがある。端的には、サーバがUnix系、クライアントがWindowsあるいはMacなどという場合はクロスプラットフォームといってよいだろう。こうした場合、サーバ側とクライアント側の実装主体は分割の対象となる。
- 開発言語
同様に、いくつかの開発言語が使用される場合、分割の対象となる。今時のプログラマーは一つの言語しか使えないなどということは稀かもしれないが、昔はよくある話だった。ここはCで、ここはFortranで、ここはjavaで、という適用言語の棲み分けがそのままチーム分けと同一であった。この分割基準は現在ではよほど特化した言語以外では意味を失っている。旧い時代の名残でもあると私は思う。
具体例はさらに多くあるが、プロジェクトを分割するにはそれ相当の合理性があるということなのだ。このことが十分に考慮されていなけば、たとえ隣の部屋のプロジェクトとの間でさえうまく連携できない。ところが、こうした法則とは逆に働く”不可解な”引力が世の中にはある。
ポータビリティ誤認の悲劇
オフショア開発で複数のベンダと取引する場合、どこか1社だけに依頼が集中することは当然ありうる。オファーの内容がマッチしているとか、優れたマネージャやエンジニアがいるとか、理由はさまざまだ。しかし、将来的なキャパシティを確保するために、オファーが遠のき気味のベンダにも助けを出さないと、というインセンティブが働く場合がある。これが逆行の引力となるわけだ。何といっても目的が救済とくれば、この引力はプロジェクトの論理的整合を超えた分割を強いることがある。
実際にあるプロジェクトでそのような事態になったのを目のあたりにした。
元々とあるベンダ1社で受注して開発していたプロジェクトのうちの一部が突然キャンセルになった。そのキャンセルになった部分の開発は発注側の企業が資本関係を結ぶ、ある別のオフショアベンダに流れていった。この2社間は地理的にもかなり離れており、しかも互いに交流のない関係だった。現場では反対の声があがったが、発注元が一部引き揚げると決めた以上どうすることもできない。
果たしてどうなったか。
元々の仕様が曖昧で手戻りが多かったのに加えてブリッジ担当者は2社間を行ったり来たりと、コミュニケーションロスが増えた。このような状況からプロジェクトの進捗は思うにまかせず、結果的にそのプロジェクトは炎上した。そのあと、どう収束したかは知らないが、当初発注を受けたベンダはまもなく経営に行き詰まり会社を解散してしまった。利益を生まないデスマーチに企業体力を使い果たしてしまったか、あるいは先行きを悲観した経営者が資本を引き揚げてしまったか、そんなところだろう。ともかく、この出来事に関係者は驚愕した。
この事件の背景には、現地ベンダとの信頼関係の問題があると私はみる。当初からずっと現地ベンダの意向はまったく顧みられていない。プロジェクトの分割による作業効率の低下は黙殺されている。無理矢理にプロジェクトの一部分を切り取っても100%のポータビリティを可能にできるという誤解がある。実際、こうしたケースでもリソースを追加し人海戦術でなんとかなるだろうと考えられる向きもある。しかし現実、人海戦術で解決できることはそんなに多くはない。火に油を注ぐの例えに近い状況になった事例は数知れない。量ではない。いかに効率的、合理的に仕事を進めるかが重要なのだ。
なにはともあれ、たった一つのプロジェクトの失敗が会社の崩壊につながるとは、プロジェクトを分割した当事者を含め誰しも予想もしなかっただろう。しかし、もしも当初の体制通りに1社で開発をしていたら、大成功とはいかなくても会社は存続できたかもしれない。もし開発途中でこのような事態になると、最終的にはクライアントに提供するサービス品質の低下に帰結する。これが避けられない事態となることも忘れてはいけない。
マイクロマネジメントの誤解
ベンダとの信頼関係ということに関しては、製造工程の進捗の把握方法にも様々な影響を及ぼすことがある。毎週はともかく毎日のたとえばプログラム行数など出来高を逐一把握することでプロジェクトの見える化が完璧であると錯覚する人がいる。だが、元々仕様の理解浸透度がプロジェクトの成否の決め手であるとの持論を持つ私にとって、製造工程での出来高を細かにモニタすることに大した意味を感じない。問題を解決する目的に沿って作られないプログラムコードは価値を生まないからだ。そうしたプログラムコードはのちのち破棄するにも手間がかかる状況があることを想定すれば、これは価値としては寧ろマイナスである。それを逐一把握することは場合によっては必要であってもあくまで手段であって目的ではない。
立場を変えてみよう。
毎日毎日書いたプログラム行数を報告させられるプログラマの負担はどうだろう。報告のために使う時間もその日の作業を終えて帰宅する直前の5分10分と短くとも、数週間・数ヶ月で累積すると延べ数時間と無視できないロスになる。それにテストを書いているとき、リファクタリングでソースコードを整理しているとき、これらの重要な作業にも関わらず出来高は微々たるものに見えてしまう。むしろ無駄に冗長なコードを大量生産するエンジニアの方が高評価になってしまうおそれがあるのだ。
何よりこうした非生産的な作業の強制はエンジニアのモチベーションに影響する。これが一番の問題ではないだろうか。何より実際に手を動かしているのは人間であるということをよく理解しなければいけない。
そのようなことに貴重な時間を使わせるくらいなら仕様に関するコミュニケーションを濃密に行う方がよほど有効だ。その方が確実にプログラムの精度が上る。もしプログラムの出来高がどうしても知りたいという人は、ヴァージョン管理システムの例えばGitやSVNリポジトリから毎日差分を自動検出するなど工夫をすればいいと思う。そういう作業は機械の仕事だ。思考と感情を持つ人間であるエンジニアはそういう束縛から解放しなければいけない。
よくも悪くも、人間と人間の対話を経て人間自身が生み出すものがソフトウェアである。我々はプログラムコードを相手にしているのではない。人間を相手にしているということを常に意識すべきだ。
いかなる場合にても、喜び大ければ大なるほど、それに先立つ苦しみもまた大なり。
アウグスティヌス