いものやま。

雑多な知識の寄せ集め

ソフト開発における「設計」とは何なのか。(その8)

前回は要件定義のやり方について書いた。

今回はそれに付け加える感じで、ユースケース記述の話。

ユースケース記述

ユースケース記述というのは、システムがどのように使われるのかという一連の流れを書いたもの。

一例を挙げると、たとえば「ユーザがログインする」という場合なら、

  1. ユーザがブラウザで特定のURLにアクセスする。
  2. システムはログイン画面を表示し、ユーザにメールアドレスとパスワードの入力を求める。
  3. ユーザはメールアドレスとパスワードを入力し、「ログイン」ボタンを押す。
  4. システムは入力されたメールアドレスとパスワードで認証を行い、認証ができたらユーザのマイページを表示する。

みたいな。

このユースケース記述というのはシステムを外部から見たときの振る舞いを規定するものなので、要件定義というよりかは基本設計で考えるものではあるんだけど、できれば要件定義の中で追加でやっておいた方がいいと思っている。 なんでかというと、このユースケース記述をお客さんに共有することで、実際に自分がそのシステムを使うときの様子をイメージしてもらうことができるから。 この段階で「思ってたのと違う」というのが分かれば、システムを作り出す前に方向性の修正ができる。

このユースケース記述はシステムの内部の動きについては細かく書かないので、お客さんも理解できるギリギリのところにある設計となっている。 なので、ユースケース記述を共通言語してシステムの振る舞いを積極的に議論しておくといい。

ちなみに、このユースケース記述をちゃんと作れるかどうかが設計の肝なところがある。 というのは、近頃ドメイン駆動設計(DDD)が声高に叫ばれてたりするけど、このユースケース記述の中に出てくる用語や概念、その適切な値、振る舞いといったものが、まさにドメイン知識だから。

ドメイン駆動設計をやろうとして、でも何がドメイン知識なのか分からないみたいな話を聞くことがあるけど、それはドメイン知識を抽出する方法を知らないからだと思っている。 ドメイン知識というのはユースケース記述から抽出するものなんよね。 そして、ユースケース記述から抽出するからこそ、お客さんとの共通言語としての機能を果たせるというのがある。 オブジェクト指向分析設計でこのあたりの知識は語られてるはずなんだけど、なんか抜け落ちてしまっているせいで、テクニックに走りすぎて実際のドメイン知識はスカスカの軽量DDD(というか形骸DDD)が生まれてしまってると思うんだよなぁ・・・オブジェクト指向分析設計がちゃんと復権してくれるといいんだけど。

ユースケース記述のポイント

さて、ユースケース記述を書く上で、いくつか気をつけたいことを書いておきたい。

まずは、個々のユースケース記述をやっていく前に、ユースケースの一覧を用意しておくこと。 一覧で見れるようにしておくことで、ユースケースに抜け漏れがないかを確認しやすくなる。

一つ注意したいのは、このユースケース一覧というのは、システム全体のユースケースじゃなくて、今回の開発対象のユースケースということ。 全部のユースケースを書いてたら、いくら時間があっても足りないので。

そして、ここのユースケース記述をするときに気をつけたいのは、「主語」。 ここでもやっぱり主語が重要。 日本語だとついつい省略しちゃいがちなんだけど、「誰が」何をやるのかをハッキリさせておかないと、あとで「あれ?」ってなることが出てきやすい。

たとえば「毎日9時に在庫情報に矛盾がないか確認する」みたいな記述があると、誰がこの確認をするのかがハッキリしない。 決まった時間という意味ではシステムがやりそうな感じがあるけど、9時という時間だと管理者がやる可能性もワンチャンありそうな。 ましてやこのあとに「在庫情報に矛盾があった場合、修正を行う」みたいな記述が続いてたら、管理者が確認してシステムに修正情報を打ち込むのか、システムが確認して修正できるところを自動で行うのか、みたいになってくる。 いずれにせよ、解釈に揺れが生じて、「思ってたのと違った」となる危険性が高い。

あと、主語を書くときに、ユーザ側については「ロール(役割)」も意識した方がいい。 同じシステムであっても、管理者ができることと一般ユーザができることというのは違ったりする。 なので、単に「ユーザは顧客情報を入力する」「ユーザは使用明細を見る」のように書くのではなく、「管理者は顧客情報を入力する」「一般ユーザは自分の使用明細を見る」のように、どのロールで振る舞った場合のユースケースなのかが分かるような主語になっているといい。

他には、システムがバッチで動くとかなら「いつ」動くのかとかもちゃんと書いておきたいかな。 まぁそんな感じで、システムの外側から見た振る舞いに関して、できるだけ曖昧なところが生じないように書いて合意をとっておけるといい。

一方で、ついやってしまいがちなのが、システム内部の処理を細かく書きすぎてしまうこと。 この条件ではこう計算してとか、ループをどう回してだとか。 ユースケース記述を書くのって、フローチャートを書いてるのに近い感じはあるからね。

ただ、そういった内部の動きはお客さんも言われても困るだけから、書いてもしょうがない。 なので、システム内部の細かい動きには触れず、ユーザとシステムのちょうど境界の部分について書けるといい。

要件定義書に書くといいこと

ということで、要件定義書に書いておくといいことは、以下のような感じ:

  • 開発の目的
    • 顧客が何を望んでいるか
      • 深掘りして、要件に繋げられるレベルにしておく
    • リファクタリングなら、開発者が何を望んでいるのか)
  • 要件定義
    • 要求を満たすために、開発者は何を行うのか
      • 〜〜機能を新しく作る
      • 〜〜機能を修正する
      • (〜〜機能を廃止する)
      • (開発後にシステムが満たしているべき条件(非機能要件))
    • 検討したけど実施しないことは何か、どうして実施しないのか
  • ユースケース

このレベルでお客さんと合意が取れていると「思ってたのと違った」というのが起こりにくいし、開発者側もドメイン知識の抽出やシステムの作りをイメージしやすくなる。

今日はここまで!