システム開発を請け負うものにとって最大の難関と位置づけられているのが「最上流」の工程である「要件定義」工程である。
要件定義とはシステム開発の最初の工程であり、これから作ろうとしているシステムを使うユーザー部門から要件をヒアリングし、システムに実装すべき機能を整理して決めていく工程である。業務要件をシステム要件として定義していく工程とも言い換えることができる。
SIerの一次請け企業のシステムエンジニアとして長年の経験を持つ管理人から見て、要件定義に失敗しているプロジェクトは大抵炎上していることが多い。その理由は要件が決まってないからである。要件が決まらないまま、後続工程に突入すると、仕様変更や手戻りが多発し、極端に品質が劣化する傾向にあるのだ。
開発を担当している側は要件定義が収束していなくても、なあなあで後続工程に突入してしまう理由はよくわかる。顧客との力関係でなかなか「要件定義が完了していないので、プロジェクトのスケジュールを延期させてください」とはいえないのである。
こういったことが背景にあり、顧客の”要求”を”要件”に落としていく「要件定義」の方法論を語る書籍は数多く存在している。しかし実は要件定義工程に失敗すると炎上する理由のもうひとつの側面について語られていることは少ない。
それは「開発の難易度を決定しているのもまた要件定義である」ということだ。
つまり要件定義を間違えれば開発の難易度は高くなり炎上の可能性が高くなり、要件定義に成功すれば開発の難易度は低くなり、炎上する可能性も低くなるということである。
管理人である私が、この側面が見逃されがちであると考える理由は、要件定義を語る人間の多くは優秀なプロジェクトマネージャーであって、優秀な開発者ではないからだ。優秀なプロジェクトマネージャーは顧客からヒアリングした要求を要件としてまとめることは得意である。しかしまとめた要件が開発しやすいかという観点まで踏み込んで要件をまとめてくるプロジェクトマネージャーは少ない。
これは仕方のないことで、現場の指揮官であるプロジェクトマネージャーはいちいちその要件が、実装するにあたってどのくらいの難易度があるかということまで気にしていられないのである。
もちろん現場たたき上げのプロジェクトマネージャーであれば自然とそういった観点が身についていて、開発しやすい要件にまとめてくれることが多いが、プロジェクトマネジメントしかやってこなかったようなPMになると、実装の難易度という観点がぽこっと抜け落ちていることがある。
そのためそういったプロジェクトマネージャーがまとめるプロジェクトでは、要件をまとめたはいいが、開発の難易度が高くなり、スケジュールの遅延を招いたり、テスト工程において障害が多発するといった事態に陥りがちなのである。私は現場のシステムエンジニアとしてこういった難易度の高い開発を行ったがゆえに炎上したプロジェクトをいくつか経験している。
そのたびに思うことが「このプロジェクトは要件定義で負けている」ということだ。
管理人である私は幸いにも開発のたたき上げからスタートし、現在は顧客と要件を詰めるような仕事をさせていただいている。システム開発の一次請け企業の中でも、業務要件をシステム要件に落とし込む要件定義工程を最も経験している一人であると自負している。
そんな私から見て、炎上しないプロジェクトにするためには、要件をきれいにまとめるだけはなく、”開発を楽にするための要件定義”というのが非常に重要だと感じている。そしてその方法論については現場の開発者目線とユーザーとしての業務目線の両方を理解していなければわからないことであるためか、語られていることはほとんどない。
そこで今回は”開発を楽にするための要件定義”の方法論について解説したいと思う。
本日お伝えする内容は以下の内容である。
- 要件定義が後続工程にどのような影響を及ぼすのか知ることで、要件定義時に抑えておくべき事項を理解する
- 高品質な開発そして高生産性は、まず要件定義から始まることを理解する⇒というよりも要件定義で勝負はほぼ決まっている
- 要件定義は開発フェーズでも続くが、開発工程を行う人間が要件定義に積極的に関与(コントロール)していくことで開発が劇的に楽になることを理解する
- 多くの場合、高次元の品質と生産性は同時に達成されることを理解する⇒生産性:○、品質:×ということはないし、逆もしかり
ソフトウエアの品質と生産性とは?
これから”開発が楽になる要件定義”というテーマを話すにあたって、”品質”という言葉の定義ははっきりとさせておく必要がある。ここで主に言いたいことは、難しい機能を作ることが品質のすべてではないということだ。顧客の満足度というのは開発の難しさに比例するということはないのである。
順を追って説明していこう。
開発を生業にするものにとっては当たり前の話であるが、”品質”にはいろいろな種類がある。たとえば開発におけるソフトウエア製品の品質には内部品質と外部品質があり以下のように定義される。
- 内部品質=「設計仕様」と「プログラム」の合致度合い
- 外部品質=「ユーザの要求」と「設計仕様」の合致度合い
- 利用時の品質=「ある製品が、指定された目標を達成するために用いられる際の、有効さ、効率、ユーザの満足度の度合い」
これらの関係を図にするとこんな感じとなる。
ここからわかるように、私たちシステムエンジニアが最も重視すべきはユーザの満足度である”利用時の品質”である。そして要件定義工程では、この”利用時の品質”の上限を決める作業であるともいえる。
開発工程では、どうがんばろうとこの要件定義時に決めた”利用時の品質”を上回ることはなく、この品質にどれだけ近づけるかが求められる。言い換えれば利用時の品質から作ったものがどれだけ差分があるか(=劣るか)というマイナス評価になっていくのである。
これから話す”品質”というのはもちろんこの”利用時の品質”を指しているということを覚えておいてほしい。
次にソフトウエアの生産性についてであるが、明確な定義はないが先ほどのソフトウエアの品質に合わせると以下の項目があげられる。
- STEP(ソース行数)/MM=内部生産性(決まった設計を満たすプログラムをどれだけの工数で実現できるか)
- FP(ファンクションポイント)/MM=外部生産性(決まった要件を満たす機能をどれだけの工数で実現できるか)
- VALUE(価値)/MM=”創出価値”の生産性(ユーザーにとっての価値をどれだけの工数で実現できるか)
ソフトウエア開発に従事しているものならもうおわかりだと思うが、開発の生産性を語る指標は上から下に目指すべきものが変わってきている。
STEP/MMを指標にした場合、同じ機能であってもたくさんコードを書けばいいことになり、冗長性などを無視した評価になってしまう。またFP/MMを指標にした場合ではたくさん機能を盛り込めば生産性が高いということになるが、機能が置ければ顧客が満足するかといえば違うのである。
そのため近年はよりユーザー目線にたった考え方であるVALUE/MM、つまり創出価値の生産性という指標が重んじられるようになっている。この指標だけ見ればすでに言いたいことの8割方伝わるような気もするが、”たくさん作ればいい”という時代は終わったのである。言い換えれば顧客の満足度を高いならば、小難しい開発を行わなくても生産性は高いのだ。
こういったことを頭に入れながら以降の話を進めていこうと思う。
要件定義と開発の品質・生産性の関係
ここでは具体的に要件定義のやり方やコントロールの仕方によって、開発の品質・生産性がどう変わってくるのかを実例を使って検証していきたいと思う。
そのために機能要件と非機能要件にわけて紹介していく。
機能要件から
例えば以下のようなシステムにおいて仕様変更要求が来たとする。例示しているシステムはわかりやすいようにかなり簡素化していることはご容赦いただきたい。
【現行業務フロー】
- 情報とシステムに登録すると、自動で登録した情報をもとに外部システムに報告がされる
- 外部システムに報告されたデータでエラーがあれば、システムにエラーデータとして登録される
- オペレーターはエラーデータを参照して、エラー内容を修正し、再報告を行う
【仕様変更要求】
「エラー参照画面に商品コードでの検索を追加してほしい」
現状の業務フローでは、エラーデータが多く発生し、業務オペレーターは商品ごとに担当が決まっているため、自身の担当する商品のエラーについてまとめて検索したというものである。
今回の仕様変更に関して詳しく顧客にヒアリングしてみると、以下のように問題点を整理することができた。
【表面上の問題点】
「担当者が報告エラーを参照する際に、すべてのエラーから自分の担当商品の取引を選ぶのが大変なので、報告エラー参照画面の検索条件に商品コードを追加してほしい。」
まずいっておくと、こういった顧客の要求事項(特にかなり具体的な・・・)をそのまま受けて開発するのは3流ベンダーである。それは簡単に理解してもらえると思う。
こういった具体的な要求仕様が出てきたときは、要注意である。顧客の本当のニーズはそんなところにないことが多いからである。そこで我々のような要件定義を行う人間は少なくとも、表面的な要求事項の裏に隠れている本当のニーズや問題点を聞き出す努力をしなければならない。
今回も顧客と話して、よくよく聞いてみると以下のようなことがわかった。
【本当の問題点】
「日々発生する報告エラーが多く、それを修正するための作業も煩雑で、時間が掛かっているため、報告エラーの修正業務を効率化したい」
さて、この真のニーズを解決するために、「商品コードを検索条件に追加する」という機能追加は果たして一番有効な解決策であろうか?
こう聞かれれば、誰でももっといい解決策を考えることができるだろう。例えば以下の案だ。
【より良い解決策の提案】
「一括報告エラー修正画面を新規に開発し、エラー理由や商品コードで検索して、該当した複数の報告エラーを一括で修正できるようにする。」
さて、これならどうであろうか。顧客から提示された要件よりも、効果的な解決策を提案できたのではないだろうか。
このように顧客の要求というのは、ときに具体的すぎることがある。業務に詳しいからといって全体が見えているわけではないのだ。そのときにわれわれシステムエンジニアは、顧客の真のニーズをヒアリングして、それを解決することが求められる。
ちょっと待て。
これで終わりか・・・
ここで終わると、それは冒頭で述べたただの要件のヒアリングがうまいだけの要件定義である。今回の本題は”開発を楽にする要件定義”なのだ。
さきほどの【より良い解決策の提案】では、顧客の真のニーズは解決できるかもしれないが、新規画面を作ることになるし、当初聞いていた要件を実現するよりも確実に難易度は高くなってしまっている。
ここからが”開発を楽にするための要件定義”である。
まずは、本当の問題点をさらに深堀できないかを考えることからはじめる。
”そもそも”、”なぜ”、そんなに多くの報告エラーが発生しているのか考えて見よう。
この観点でさらにヒアリングしてみると、実はユーザー(オペレータ)の報告マニュアルの編集仕様が一部間違っていることがわかった。
そこで一部間違っていた、マニュアルの報告編集仕様を訂正してもらったところ、報告エラー自体がほとんどなくなったのだ。
ここで、この例について振り返って見る。
まず利用時の品質について。
顧客は当初、エラーの修正業務が大変なので、その業務を効率的にしたいということを望んでいた。それに対して今回の根本的な解決策によってどうなったであろうか。
業務の効率化以前に、報告エラーの修正業務自体がなくなったことで、より高次元においてユーザの目的が達成されたことがわかると思う。
次に外部品質と内部品質を見てみよう。
これは最大値を達成している。なぜならば、何も作っていないからである。何も作らなければバグはゼロである。
最後に利用時の生産性を見てみよう。
利用時の生産性は無限大である。なぜならば、何も作っていないから工数は0である。
顧客の当初の要件以上のことを達成し、しかも工数はゼロなのである。
どうだろうか。
まず作るだけがすべてではないということは理解していただいたと思う。そしてどのように要件定義を行うかによって、ユーザーの満足度、そして一番重要な品質と生産性が変わるということがわかったと思う。
非機能要件から
次に非機能要件の仕様変更に対して、例を示す。
以下のような帳票を作成するバッチ処理があったとする。
上図のように、前日のマスタと当日のマスタを使って、帳票を作成する処理である。現状AM2:00から作成し始めて、AM10:00に帳票が作成されている。
そこに以下の仕様変更が来たとする。
【仕様変更要求】
「帳票をAM9:00までに出してほしい」
さて、みなさんならどうやって顧客の要望を満たすだろうか。
おそらくまずは処理性能のチューニング、いわゆる性能問題として考えるのではないだろうか。
確かに性能問題として考えれば、
- データベースのアンロード処理の短縮化
- ファイルの転送処理の短縮化
- ファイルの暗号化・複合化ロジックの短縮化
- 抽出処理の並列化
などなどチューニングできそうなところはいくらでもある。これらを行えば確かに顧客に提示された要件は満たせそうである。
しかしこういったチューニングはかなり工数を要するし、バグも埋め込みやすいものである。顧客の要求をそのまま受けると無謀とも思えるゴールがないかもしれない性能のチューニングを行わないといけなくなるのである。
さてここまでお読みいただいた読者の方ならばおわかりになると思うが、こういうときは”そもそも”、”なぜ”、帳票を9時に出さなければならないのか?ということを確認してもらえると思う。
しかし今回の場合は、真のニーズを確認しても確かに帳票を9時までに出さなければいけなかったとしよう。
そんなときに非機能要件を機能要件に置き換えて考えるということを考えてほしい。
どういうことかというと、”そもそも”帳票には何が出力されていて、ユーザは何の目的でその帳票をしようしているのかということを考えてほしいのである。
これが非機能要件の問題を機能要件から見直すということである。
今回の問題について、その帳票をどのように使っているのかを突き詰めて確認した結果、当日マスタから作っていた内容は、実は前日マスタから作っても同じことができたのだ。つまり当日マスタの作成を待つことなく、前日マスタから該当の帳票出力処理を動かして問題なかったのである。
そこで今回の問題に対しては、以下のようにジョブを組み替えて、並列処理を行うこととした。
どうだろうか。
顧客の要件であった、「帳票を9時までに作ってほしい」という要望を完全に満たすことができた。それもかなりの時間の短縮になっている。
今回の問題を振り返って見ると、通常ならば性能問題として要件定義を行うところを、機能要件の問題として捉えることで、より高次元に顧客の要求を実現できることを示した。
利用時の品質を見てみる。
これは前日マスタから作ってもユーザがやりたいことは実現できているし、当初の要求よりもかなり大幅に時間を短縮することができた。
次に外部品質・内部品質を見てみよう。
外部品質は当然のことながら、9時までに帳票を作成できているので、満点である。そして内部品質はジョブの組み換えだけのためバグゼロは容易に達成可能である。
最後に生産性はどうであろうか。
性能問題のチューニングだとするとゴールの見えない無謀なチャレンジで、様々なチューニングを駆使しなければいけないため、工数は膨らみそうであったが、単純なジョブの組み換えだけならば、相当少ない工数で実現できそうである。生産性は何十倍にもなったと思われる。
開発を楽にするための要件定義
それではまとめに入っていこう。
今回提示した例からもお分かりいただけるように、要件定義で上限品質というのは決まってしまうのである。
それ以降の工程ではどんなにがんばってもマイナス評価である。そして作れば必ずバグが出てしまうものである。
極論であるが、「だったら作らなければいい」のである。
作らないで顧客に、作った場合と同等以上の価値を提供できれば、開発の品質は上限値であるし、生産性は無限大となる。
今回お伝えしたい”開発が楽になる要件定義”の方法論をまとめると以下である。
- 提示された要件に対して”そもそも”、”なぜ”必要なのか繰り返す⇒一旦極論まで引き上げて、現実解に下げていくことで根本的な解決策を見つけることができる。(”そもそも”エラーデータの報告は不要では?”そもそも”この帳票っていらないのでは?)
- 要件が具体的過ぎたら要注意(~の項目を追加してほしい等)⇒手段を要求されたら必ず目的まで遡って検討する
- 無意識に”制約”や”前提”、”対象外”を作っていないかを確認する。⇒「報告エラーが出るのは前提」、「当日マスタから帳票を作るのは制約」
このように考えることで、要件定義工程で、後続の開発工程を楽にするためのシステム要件を実現できることが多いのだ。
重要なのは、単純に顧客に聞いてもわからないことが多いということである。顧客のほうが無意識に制約に縛られていて、根本原因や根本解決策を思い至らないことがあるのだ。
そのため外部のものである我々が、”そもそも”という質問を投げかけることによって、真のニーズであったり、それを解決するための楽な方法に至る可能性が高いのである。
この記事を見ていただいた優秀なシステムエンジニアは、ぜひこの”開発を楽にするための要件定義”を実践してみてほしい。
※ただし注意事項として、”作ることが仕事”である場合もある。これは道路工事と同じで、一定以上の開発を行うことが幸せであることもあるのだ。そういった場合は、この”開発を楽にするための要件定義”は逆に困ることになるので注意が必要だ。