なぜ大規模なシステム開発は失敗するのか
みずほ銀行のトラブルがなかなか収束しない。開発段階から、業界内ではプロジェクトの様子が話題になっていた。人類が過去作り上げた最も巨大な建造物「クフ王のピラミッド」よりも、多くの人月をかけて作られていることとか。開発しても開発してもうまくいかず、解消するために次々開発していること。そのため無限に人が必要になり、業界でブラックホールプロジェクトと呼ばれていたこと。劣悪な労働環境で、プロジェクトに参加しているエンジニアは疲弊していること。
伝え聞いているだけだけど、ダメになる要素を全て踏んでいるような話だった。それにしても大規模なシステム開発というものは、とにかくうまくいかないことが多い。なぜ大規模開発はうまくいかないのか。うまく進めるためにはどうしたら良いのか。せっかくなので、ちょっとまとめてみた。
現行業務がわからない現状
さまざまな企業と話していると、自社の業務を正確に把握している企業は、実はほとんどないのだというのがわかってくる。今や、業務のほとんどはコンピュータ化されている。なので、業務内容を理解することは、コンピュータの中でどのような処理をしているのかを理解することと同義となる。でも、通常は毎日意識しないままコンピュータが動き、業務は進む。だから、わかっていたこともわからなくなり、自社の業務に関する知識はドンドン失われているのだ。
例えば特定の仕事を受注するために、相手と特別な条件で契約をしたとする。毎月や毎年の請求を間違えないように、システム化をする。そんな顧客が何社もあると、そもそも全体を把握するのは難しくなる。契約書に書かれていることもあるけれど、書面に書かれていることは基本的なことだけだったりする。だから、なぜそうなのかを調べる手段はない。そんな経緯も知らず基幹システムの再構築を始めると、こうした「なぜそうなってるのかわからない」ことが、次々出てくる。
機能を足し算して複雑化するシステム
そして状況を悪くするのは、せっかく再構築するなら、欲しかった機能を色々と追加しようとする間違いだ。
使いやすいと感じるものは、大抵の場合、シンプルさと裏腹だったりする。単純さはわかりやすさでもあり、間違えにくいことにもつながる。なのに多くの基幹系再構築は、機能を次々に追加しようとする。しかも、業務の全体像について本当のところは把握できていないのに、無邪気にも機能追加をしてしまい、動かしてみると辻褄の合わないことが次々起きてしまう。
把握していなかった業務仕様と追加しようとしている機能との間に矛盾があっても、ちゃんと動かないことを指摘して開発ベンダーの作成したソフトウェアにバグがあるのでなんとかしろと言って修正を迫る。言われたベンダーもどうしていいかわからないので、とにかく結果が辻褄合うようになんとか頑張る。結果、仕様が根本的に間違えているという本当の原因は隠蔽され、何ヶ月後か、何年後かにトラブったりするが、その時は開発したエンジニアも現場を離れていて、なぜそうなったのか調べる手立てもなくなってたり。なんて、最悪なことが現実に起きている。
一体どうしたらいいのか?
やるべきことは、シンプルさ、マイクロサービス、、SaaS、インクリメンタルの4つだ。
シンプルな構造にする
まず考えるべきは、全体の構造をできるだけシンプルにすること。
コンピュータシステムの構造は、単純に考えると、登録・処理・検索・分析の4つに分かれる。登録は、業務の情報を登録する部分。登録された情報は、加工・集計をされて別の形に保管される。この部分が処理。そして登録したり加工されたデータを検索する部分。そして検索と極めて近い機能だけど、様々な形式のグラフにして、状況を俯瞰する分析。
最近のテクノロジーは、大量のデータを超高速に処理する技術が高度に発達している。だから、データを様々に加工・集計する部分は、そうしたテクノロジーを駆使して、簡単かつ高速に処理できるように考えてみる。当たり前だけど処理の部分が一番複雑なので、ここがシンプルにできれば開発全体はとても単純なものになっていく。
データを加工・集計しやすい構造に入れることで、分析は普及したツールで行なうことができるようになる。開発する必要のないものは、そもそも作る必要なんてない。作ることが尊いのではなく、作らないで終わらせることの方が、よっぽど価値が高いのだ。
マイクロサービス
そして2番目のマイクロサービス。
全体が極めて大きなシステムであろうとも、大きな一つの塊として開発するのではなく、分解可能な機能が組み合わされた物として開発をしていく。それができれば、追加したい機能があったり、変更したいところがあっても、全体を見直すのではなく、部分的改修で済むようになる。
こうしたことを実現しようとするなら、自力でサーバーを立てて行うよりも、クラウドサービスを使う方が断然いい。一般的に、基幹系開発では、全体工数の3割近くを環境構築に喰われていたりもする。インフラを忘れ、スケーラブルな構造も作りやすい基盤を選び、マイクロサービス的な構造でシンプルに完成させることは、もはや特別なことでもないので、構築できる技術者は世の中にたくさんいる。
使えるものは使う
次に考えるべきは、SaaS(もしくはクラウド)。つまりシステムの全てを自力で開発しようとしないことだ。利用できそうなサービスがあれば、積極的に使う。それはアプリケーションサービスかもしれないし、もっとインフラ的なものかもしれない。要は、クラウド上に存在して、個別にサーバーなどを購入しなくても良いものを選ぶのが断然良い。
使えるものは使うという姿勢をとれば、開発しなくてよくなる。とはいえ自社独自のことをやりたいとするなら、SaaSとのデータ連携をマイクロサービス的に構築し、自社が利用している大量データ処理基盤と連携させる。
インクリメンタル(プログラムはどんどん捨てる)
そして最も重要な4番目の要素が、インクリメンタルだ。
冒頭にも説明したように、開発しようとしている業務は、誰も全貌を理解していない可能性が高い。しかも将来を見据えた機能などという要素が出てくると、わからないことはさらに多くなる。
だからやるべきなのは、一度に大きな仕組みを作るのではなく、少しずつ完成に近づけていくこと。しかも、途中まで作ったプログラムを捨てながら完成させていくことだ。
若い頃、米国Apple社の純正通信ソフトウェアを開発していたことがある。開発難易度はかなり高く、試行錯誤しながらでなければ進められないものだった。ある時、1ヶ月かけて作成したプログラムを誤って削除してしまい、途方にくれたことがある。仕方ないので、そこまでの記憶を頼りにもう一度開発し直したら、なんと3日で完成してしまった。しかもプログラムはかなりシンプルになり、実行速度は格段に早くなった。
システム開発とは人を育てること
つまりブラッシュアップさせなければならないのはプログラムではなく、開発者本人なのだ。一度答えが見えたら、プログラムなんか捨ててもいい。答えが見えたエンジニアの存在こそが重要で、そこからもう一度開発させたら、格段に良いものができるのだ。
だから、答えがよく見えない状態で着手しなければならない開発は、全体の基本的な部分から少しずつ開発をしていき、答えを探していくべきだ。それはなんのためにするのかというと、プログラムを徐々に完成させるために行うのではなく、開発者の練度を徐々に上げていくために行う。答えの見えなかった業務を、少しずつ見えるために行う。そして、見えたところでプログラムは一旦捨てる。(必ず捨てなければならないわけではないけど、ここまでくれば、捨てても大したことない)大切なのはプログラムではなく、答えが見えたチームだ。そのチームでもう一度プログラムさせたら、はるかに良いものができるはずだ。
だから、あえて言うと、システム開発とは、人を育てることなのだ。
当たり前だけど、わかっている人が作ったシステムは、良いものになる。開発初期は、発注側もよく分かっていない。だから、インクリメンタルに開発をしていき、何を作るべきなのかを作りながら確認していくのだ。やってはいけないのは、この段階で、何を作るべきかを文章だけで表現すること。文章として書かれたとしても、それがちゃんと動作するものかはわからない。なので、ちゃんとプログラムしてみる。ちゃんと動かして確認してみる。そうすれば、その機能が正しかったのかどうかはわかるはず。そうやって何をすべきかをプログラムしながら獲得していく。人間に、知識や経験として獲得させていく。そして、一旦全てを捨てて、習熟したチームで本当の開発をしていく。
そんな余裕のある開発の仕方はできない。と思っているかもしれないけれど、開発してみたものの仕様が食い違っていたり、動かしてみたけどバグがなかなか消えなかったりして、結局延々と時間をかけてしまうのと比較したら、きっと本当の完成までは、断然早いはず。
あ。そうそう。こういった全てのことを実現できるのが、グルーヴノーツのMAGELLANだったりするのだけれどね。