常識かと思ってましたが、業界人であっても開発経験のない人には伝わらないことが多いので、書きます。
なお、ウォーターフォール型といっても明確な定義があるわけではないので、ありがちな以下のモデルを題材にします。
なぜ失敗するか
ウォーターフォールの各フェーズの作業内容や成果物を上記のように定義すると、非常にわかりやすいです。が、失敗します*1。
要件定義/外部設計は、客がこう言っていた/客が言ってることを実現する画面はこんなのだ、という形で簡単に進んで、内部設計段階で詰まります。なぜなら、外部設計成果の実現可能性を検証していないから。
- ある画面と別の画面との処理内容がどうやっても競合する
- 画面表示に必要なデータを抽出できない
こういう問題が噴出します。そしてそもそもどういう前提で外部仕様作ったんだよ上流は、というネットでよく聞く上流対下請けの構図になります。
単純な話です。
どうすればよいか
本来の意味での設計(デザイン)が必要です。設計とは矛盾なく整合した実現方式・方針(≒アーキテクチャ)の検討です。
外部設計書や内部設計書の作成はその共通方針に基づいた個別項目の詳細記載で、外部設計や内部設計より前に「アーキテクチャ設計」は終わっているべきなのです。
設計を単に別の人が書いたものを変換する単純作業ととらえるから失敗するのです。
うちのプロジェクトにはそんなフェーズ全くないよ?という方。設計開始時に「なんでも相談できる人」が配置されて仕様を相談できるようになってたりしないですか?そうであるなら、アーキテクチャ設計結果は彼の頭のなかにあります。
システム開発経験がない人の勘違いは、「システム開発手法」のような普遍的な方法があって、それにそって文書を整備していけば自動的にシステムは出来上がる、というのが一番多い印象です。
こういう先入観で入ると、アーキテクチャがなにを意味しているかわからなくなってしまいます。プログラミングのこと?プログラミングのスキルはないしなあ、といった具合に。
かくして設計書のレビュー率を上げるとか、そういう頓珍漢な施策に走って更に事態を悪化させることになります*2。
成功することもあるのはなぜか
これだけ見ると、ウォーターフォールプ型開発は教科書通りやると毎回失敗するように見え、プロセスとして致命的な欠陥があるように見えます。しかし、現実には毎度毎度すべてのプロジェクトが炎上するわけではありません。なぜでしょうか。
理由1:アーキテクチャが固定化している
- 既に実現したことのあるプロジェクトのパターン違い
- 既存の納品物の改修・改訂
- パッケージアプリケーションを中心としたSI開発
などは教科書どおりのウォーターフォールでも失敗しないことが多いです。なぜならアーキテクチャ=矛盾なく整合した実現方式・方針が関係者間で既に共有できているからです。
結局のところ、アーキテクチャが皆で共有されていれば、そのレビューを行うこともでき、問題をコントロールできるのです。
ところで、外部設計の成果物セットとして、「画面設計書」「論理DB設計書」「ファイル設計書」などが定義されることが多いですが、外部設計という外から見える機能を定義するフェーズにも関わらず、「DB」「ファイル」のような物理名称が用いられることに違和感を感じないでしょうか。
あれは、実質的にはクライアント・サーバー(クラサバ)型アーキテクチャの成果物文書なのです。クライアント・サーバー型アーキテクチャでは、基本はDBの内容を読み書きするための画面があって、データの定義やデータの整合性の確認といった満たすべき制約はDBの制約として表現されるので、アーキテクチャ成果物資料として画面一覧、DB定義(CRUD付き)という定義がされるのは理にかなっているのです。
昨今、環境の変化や複雑化する要件に対応してさまざまなアーキテクチャが考案されており、そのいずれもクラサバモデルのようにシンプルではありません。Web3層アプリのようにビジネスロジック層の役割が強かったり、SPAのようにUI層の役割が強い場合は、それに即した設計資料が必要になるのは必然です。どうでしょうか?アーキテクチャが変わったにもかかわらず、昔ながらの設計書を使っているならほぼ炎上確実*3でしょう。
理由2:スーパーアーキテクトがいる
上でも少し書きましたが、要求と実現方式を完璧にイメージし、外部設計も内部設計も「なんでも相談できる人」がいれば失敗しません。
新しいこと(アーキテクチャが固定化されてないこと)をやろうとして、プロセス的なサポートがない場合は、プロジェクトの成功如何は結局この個人の能力に依存することになります。
アジャイル
スーパーアーキテクトがいたとして、個人の能力には限界があります。
実現方式がすべての機能をカバーできるとどうやって証明すればよいでしょうか。そもそも、すべての機能をカバーできる実現方式を、 机上で考えることができるのでしょうか。
アジャイルはこういう事態に対して「矛盾なく整合した実現方式・方針」を確立するために必然な方式なのです。
外部設計/内部設計 vs 基本設計/詳細設計
今まで、外部設計/内部設計という用語と使ってきましたが、基本設計/詳細設計という用語が使われることも同じくらい多いようです。
基本設計がアーキテクチャ設計を指していて、詳細設計の中に外部的側面と内部的側面(ユーザー操作によってテスト可能か否か)があるという意味合いだと、わたしのイメージと近いです。が、アーキテクチャ設計はテストによって検証できないので上の絵は間違っています。
なんでもよいですが難しい話ではないので、ISOだかIPAだかが定義して統一してほしいです。
- アーキテクチャ設計:矛盾なく整合した実現方式・方針の検討。テストで検証できない
- 外部設計:アーキテクチャ設計に基づく、外部(人・他システム)との入出力の定義。システムに対する入力を実行することでテスト可能
- 内部設計:アーキテクチャ設計に基づく、内部処理の定義。プログラムモジュール内の動作テスト(ユニットテスト)でテスト可能
まとめ
ウォーターフォール型開発を教科書通りやると失敗する。なぜなら、本来の設計=アーキテクチャ設計=矛盾なく整合した実現方式・方針の検討 が必要であることが教科書に記載されていないから。
となります。ポイントとしては
- アーキテクチャという単語が理解できない
- 対象とするシステムがどんなアーキテクチャで実現されるのかわからない
- 基本設計・外部設計・内部設計という用語がぐちゃぐちゃ
- 設計書体系が固定化されている
- 固定化された設計書体型に対するプロセス管理も固定化されている
といった環境で、新しいことをやろうとするときが失敗への黄色信号でしょうか。
もっとシンプルに言えば、「設計=流れ作業の単純文書化作業」という誤った価値観滅びよ、ということです。
ご査収ください。
*1:外部設計や内部設計は母数を要員数で割って、1日あたりの記載数かなんかを成果指標にしてスケジューリングする、といったプロジェクト管理をしているとこの時点で即炎上です
*2:定義したアーキテクチャによって表現する内容は変わるので、うまくいっていないのであれば普通は設計書の体系が足りない
*3:SIerなんかはさまざまな要求に対応したさまざまなシステム実現方式を経験しているはずなので、どういうアーキテクチャに対してどういう設計成果物を定義すればよいかというノウハウが溜まっていそうです。しかし、(観測範囲内では)クラサバ時代の成功体験に引きづられて(?)昔の設計書フォーマットをずっと使い続けたりして事態を悪化させることが多いように見えて嘆かわしいです。