Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

ロバストネス図を開発で活用してみた話

こんにちは。技術本部 Bill One Engineering Unit の前田です。普段はBill One のWebアプリケーション開発をしつつ、チーム内ではPdL(プロダクトリード)という役割を担っています。入社して初めてのSansan Builders Blogの執筆になります。よろしくお願いします。

今回は、『ユースケース駆動開発実践ガイド』で紹介されているロバストネス図を実際の開発で利用してみた話をします。Bill Oneに新機能を搭載するにあたり、仕様を明確にしチーム内で共通認識を取るのにとても役立ちました。

ロバストネス図について

ロバストネス図との出会い

最初に述べた通り、ロバストネス図は『ユースケース駆動開発実践ガイド』(以下、書籍と記載)で詳しく紹介されています。以前、ユースケースという概念について詳しく知りたいと思い書籍を購入したのですが、一人ではなぜか最後まで読むことができず、積読となっていました。

この話を同僚としたところ、その人もなぜか私と同じように最後まで読めていないということがわかりました。そこで、せっかくだから社内制度である Geek Seek Workshop*1 を活用して読んでみよう!という話になり、社内読書会を開催してロバストネス図の立ち位置や書き方などを学ぶことにしました。

ロバストネス図の簡単な説明

詳細な内容は書籍を見ていただくとして、ロバストネス図について書籍では

ロバストネス図はユースケースをオブジェクトの絵として表現したもの

と説明されています。ロバストネス図が持つ役割は以下のように記載されています。

ロバストネス分析は、分析と設計の間に見えにくい隙間で行われます。もし分析(すなわち、ユースケース)を「何を」として、設計を「どのように」として考えるなら、ロバストネス分析はまさに予備設計です。このフェーズでは設計に関するいくつかの予備的な仮説を行い、そしてテクニカルアーキテクチャや、利用可能なさまざまな設計戦略について考え始めます。

構成要素として以下の3つが紹介されています。

  • バウンダリオブジェクト
  • エンティティオブジェクト
  • コントローラ

バウンダリオブジェクトとは、システムと外部世界との境界(バウンダリ)で、通常はWebページや画面を指します。システムの利用者(アクター)と対話するものを指すので、Webアプリであればブラウザに表示されているページだし、外部API連携であればそのAPI自体になると思われます。

エンティティオブジェクトとは、ドメインモデル上のクラス、と表現されています。書籍では、ドメインモデルについて1章を割いて詳細に説明されており、「現実世界のオブジェクトに焦点を合わせる」、「最初のドメインモデリングにかける時間は2時間に限定する(最初のドメインモデルを完全なものにする必要はない)」など、示唆に富んだ記述がたくさんありますが、残念ながら本題とズレるため今回は扱いません。

コントローラとは、バウンダリオブジェクトとエンティティオブジェクトをつなぐ役割を持ちます。MVCモデルで言われるControllerよりかなり広い概念です。コントローラと聞くと、システムがユーザのリクエストを待ち受けるようなイメージを持ちますが、ロバストネス図ではユーザの入力行為やif文のような分岐、データの取得などありとあらゆる「処理」がコントローラとして扱われます。

そして、これらを線でつなぐことでユースケースを表現していきます。線上に書く「送信をクリックする」のような文字については、書籍ではラベルメッセージと呼称している場所が多いです。

ロバストネス図では接続において非常に重要なルールがあります。

  • 名詞は動詞とつなぐことができる。(逆もまた同様)
  • 名詞をほかの名詞につなぐことはできない。
  • 動詞はほかの動詞とつなぐことができる。

ちなみに、動詞とはコントローラのことを指し、名詞とはバウンダリオブジェクトとエンティティオブジェクトのことを指します。例えば、ページAからページBに遷移する、というユースケース(というにはシンプルすぎますが)を表現すると以下のようになります。

f:id:hiroronn:20220215141835p:plain
シンプルなロバストネス図

なお、書籍ではアクターについて上記の3要素ほど詳細な説明がないです。個人的には、処理の始点となるバウンダリオブジェクトのあたりに配置し、処理の起点であることを示すようにしておくとわかりやすいように感じました。アクターが明確である場合は配置する、のような記述はあるので、基本的には書いた方が良いと思います。

以下の画像が、書籍に記載されているロバストネス図の一つです。シンプルなものです。

f:id:hiroronn:20220215175452p:plain
書籍にあるロバストネス図(図5.7 を引用)

実際の利用

活用方法と背景

使い方は上記の通り学びましたが、「すぐに実践活用できる感じがしない」というのが読書会のなかで共通の見解でした。書籍には

ロバストネス図は、ユースケースをオブジェクトの絵として表現したものです。

との記述があり、そもそもユースケースを分析に取り入れていない状況では使いこなすのは無理だろう、という理由です。

一方、ロバストネス図単体で見ると以下のメリットがあると感じました。

  • ユーザの操作からシステムの挙動を関連づけて一つの図で表現できる
  • 処理の流れでおかしいところに気づきやすい
  • どのタイミングでどのエンティティオブジェクトが必要か気づける

また、書籍の内容を厳密に守るなら、本来であればロバストネス図を作る前にユースケースを作っておく必要があります。ただ、ロバストネス図を私が使ってみようと思うに至ったプロジェクトでは、ユースケースを作らずにロバストネス図を作りました。プロジェクトの状況としては以下のような状況でした。

  • 仕様に関して、ステークホルダーとの合意は別途取っている状態で、開発チーム主導でプロジェクトを進められる状態にあった
  • 私個人が対象のドメインに詳しかった
  • 一方、チームメンバーは対象ドメインは詳しくない
  • 対象の機能はバックエンド、フロントエンド双方に難易度が高く、各メンバーがバックエンド担当とフロントエンド担当で分かれざるを得なかった*2

チームメンバーが別々のことをやりつつ全体として機能を完成させるには、ドメインに詳しい私が仕様を明確に伝える必要があり、全体像としてフロントエンド・バックエンドを区別しないロバストネス図が親和性が高そうである、という理由で使ってみることにしました。

やってみた環境

書籍では、ロバストネス図を作るツールとして Enterprise Architect というモデリングツールが紹介されていましたが、Bill Oneでは使用していませんでした。Bill One開発チームではモデルの共有等には Miro を使っていたため、Miro上でなんとかロバストネス図を表現する方法を考えたところ、「単に付箋を色分けするだけで十分理解できるのでは?」と思いついてやってみました。

f:id:hiroronn:20220217153425p:plain
シンプルなロバストネス図(要素ごとに色分け)

結果は上記の通り全く問題ありませんでした。これだとMiroの付箋を置いて線で繋いでいくだけでロバストネス図が作れるし、使い慣れたMiroでささっと図が描けるため、ロバストネス図を作るという慣れない作業でも使い勝手の点で全くストレスなく作業できました。今回はエンジニア外への共有は必要なかったためこのような方法を取りましたが、使っているモデリングツールに合わせた方法で図形を変更するのは問題ないと思っています。

実際に作ってみたときの話

まず、ロバストネス図の各要素に対して、Bill Oneの環境と照らし合わせて改めて整理しました。以下、Miroで作ったロバストネス図が出てきますが、付箋色は上記「シンプルなロバストネス図(要素ごとに色分け)」に記載した通りとなっています。

バウンダリオブジェクト

昨今のWebアプリはSPA(シングルページアプリケーション)で構築されている場合が多く、Bill OneでもフロントエンドはReactを採用してSPAの構成にしています。SPAではそれほどページ遷移が発生しないため、バウンダリオブジェクトの例となる「Webページや画面」は少なくとも単一のユースケースでは変更されないことが多いです。そのため、実際に作るときはユーザにフィードバックを返すあらゆるものという定義付けで整理することにしました。具体的にはモーダル、処理終了時のトーストなどもバウンダリオブジェクトになるものとしました。これで、SPAであってもバウンダリオブジェクトを表現することができます。

コントローラ

これは単に誰かがやる処理と考えるようにしていました。主語はユーザ、システムなど場面によって変わります。

エンティティオブジェクト

書籍では「ドメインモデル上のクラス」と表現されています。対象ドメインによって抽出できる内容が変わるのと、最初の段階で出した概念と別の概念が現れる可能性もあったため、とりあえず出てきた用語をドメインとして表現していく、という指針でやりました。

作る流れ

まずは何か描かないと始まらないので、最低限「ユーザがこの操作をやったら最終的にはこうなっていないといけない」という部分だけ記載します。「仕訳の保存」という内容を例にすると以下のようになります。

f:id:hiroronn:20220215185912p:plain
仕訳の保存(初期状態)

本当に最低限で、「保存ボタンを押したら保存される」という内容しか表現されていません。

次に、仕訳として必要な仕様を満たせていない*3ために保存できないパターンを追加します。

f:id:hiroronn:20220215185948p:plain
仕訳の保存(その2)

次に、「仕訳としては問題ないが、そのまま保存するとプロダクトとしては良くないため、ユーザにデータを補正する旨を確認する」場合を追加してみます。

f:id:hiroronn:20220215191100p:plain
仕訳の保存(その3)

この辺りで、「だいぶ複雑になってきたなー」と感じると思います。このあとさらに条件分岐がある場合など、理解できないほどに図が肥大化しそうであれば、ロバストネス図を分割することも視野に入れたほうが良いです。最終的にはこのような図になっています。図を分けて情報が分散するより、一つのユースケースとして全体を表現したほうがいいだろうと判断し、図の配置を工夫して頑張りました。

f:id:hiroronn:20220215192538p:plain
仕訳の保存(最終形)

上記画像は実際に使った図をちょっと編集したものです。「仕訳を保存する」の位置はここでいいのか?というような細かい疑問は湧きますが、想定したユースケース(仕訳の保存)における必要な処理は網羅されており、ロバストネス図としてはこれで十分だったので開発はそのまま進めました。この記事に掲載するにあたり記載できず削りましたが、実際に使った図には保存周りの意図は文章で補足されています。

ロバストネス図を作る上で気をつけると良いと思った点

書籍にも、ロバストネス図の作り方についてさらに詳しい説明があります。その中でも実際に作ってみて以下のようなことを感じました。

技術的詳細は省く

ロバストネス図はユースケースに基づいて記載するため、技術的に細かすぎる内容は記載されるべきではないです。じゃあどこまでが技術的詳細なんだ、とは私も書籍を読みながら思っていましたが、概ね以下の言葉が出てきたら詳細に踏み込みすぎている、と思うようにしました。

  • マイクロサービス名
  • フロントエンドやバックエンドといった、実際に処理が行われる場所
  • DBやTask等の純粋に技術的な要素

このような用語が出てきたときは、その記述なしで表現できないか、別の用語で置き換えられないか?と考え直していました。

ロバストネス図で全てを説明しようとしない

ロバストネス図は、特定のユースケースと詳細設計の橋渡しを行う役割です。そのため、詳細設計で記載すればいいことをロバストネス図には持ち込まない方が良いです。

例えば、WebアプリにおけるAPI形式や個々の項目定義、値の変換方法、ドメインモデルの詳細項目などが挙げられます。仕訳の例で言うと、仕訳には勘定科目や金額など細かい概念は大量にありますが、必要にならない限りロバストネス図では言及しないようにしていました。

矢印の方向は気にしない

書籍の『ロバストネス分析のガイドラインのトップ10』の5位に以下の記述があります。

ロバストネス図上の矢印の方向について気にしてはいけません

書籍では、理由として「ロバストネス図の主要な目的に矢印の向きは一切寄与しない」と書かれています。これはその通りで、フローチャートのように流れが最重要というわけではないため、矢印を引くことにこだわる必要はないです。

ラベルやメッセージは図を明確にするために使う

例えば、「ボタンをクリックする」というアクションを考えると、コントローラにすべきかラベルとして要素の間に配置するか悩みます。この点は書籍だと「6.2 予備設計レビューの実践」の中でレビューアーと分析者の会話の中で触れられています。

書籍に説明はあるものの、明確にこうしなさいという指針はないです。図が曖昧にならないように配置するといった説明があるのみです。書籍にあるレビューアーの発言の一部を引用します。

図をもっと明確にするためには、代わりにバウンダリオブジェクトとコントローラの間のメッセージに名前をつけよう。そこにユーザーのアクション(中略)を置けば、どのコントローラがユーザーのアクションを処理するかについて一切迷わずに済むからね。

実際にロバストネス図を作ってみた際の所感を含めると、概ね以下のような考えでメッセージを書くようにしていました。

  • 条件分岐に基づいたアクションはメッセージに書く
  • 分岐が全くない部分でのユーザーのアクションはコントローラでもメッセージに書くでもどちらでもいい
    • どこに書くか細かいところに迷っても分析の漏れが見つかるわけではないので、そもそも拘らない

図をどう描くか細かいことを考えるより漏れがないこと、曖昧でないこと、見る人が迷わないようにすることが大事だと、書籍では繰り返し述べています。

図が大きくなったら分割する

先程の仕訳の例で言うと、最初は仕訳画面を開いたところから全ての操作を一つのロバストネス図で表現できないか試していました。しかし、仕訳の保存だけであの大きさになるのに全てを一つの図で描いても、描いている自分含めて理解できないと思いました。

その原因は、前提に書いた通りユースケースを整理せずにロバストネス図を作り始めたという点や、慣れる前に作り始めてしまった点などあります。図が大きすぎる、という「大きすぎる」の基準は個人の感覚でだいぶ異なると思います。何度かロバストネス図を作って、作ったロバストネス図を複数人で見て一緒に流れを追ってみる、という流れを何度かやって適切な大きさを掴むしかないと思います。書籍には

ロバストネス分析の方法を習得するには、ロバストネス図を少なくとも6枚ほど書く必要があることが経験上わかっています。

とあるので、とにかく場数を踏むしかなさそうです。

雨の日のシナリオを考える

雨の日のシナリオとは、書籍のユースケースの説明の中で出てくる用語です。書籍では、動作の90%を占めるような通常の利用を「晴れの日」とし、それ以外の代替的な利用を「雨の日」としています。雨の日は、いわゆる例外パターンのようなものを考えると良さそうです。本来はユースケースの段階で表現されているべき内容ではあります。

ロバストネス図を記載する場合にも「この処理(コントローラ)」には雨の日のシナリオはないか?」と考えると仕様の網羅性が上がります。例えば「保存する」というコントローラがあったとき「保存できないケースはないか?」と考え、それがあるようならロバストネス図に表現することで、漏れが防げる可能性が上がります。

使ってみた感想

前述の通り、ユースケース記述は行わず、ロバストネス図のみで一旦開発チームで使ってみました。プロジェクトが終わった後にチームメンバーにヒアリングしたところ、「ロバストネス図があることで、やることが明確になってとてもよかった」とのことだったので、使ってみてよかったと感じています。

また、ロバストネス図を作ってわかったのですが、どこまでがフロントエンドの責務でどこまでがバックエンドの責務か、という点は図に描くとほぼ見えてきます。なので、自然と「ここからここで値の受け渡しが必要だから、スキーマを事前に決めておこう」という会話や「ドメインレベルの制約違反をどのタイミングで検知し、ユーザに伝えるか」という会話が開発を開発を始める時点で行えます。そこで仮決めした内容でバックエンド・フロントエンド両方で分析と開発を進めてみて、なんか違うと感じたら必要であればロバストネス図に戻ってくることもできました。

ロバストネス図の大きなメリットと考えているのは、ユーザ操作とそれに伴うシステムの挙動を一気通貫で図に表せることだと思います。ただのCRUD処理を表現するには過剰なものにはなりますが、ユースケースは分析で取り入れていないという状況でも詳細設計の前段にロバストネス図を挟んでみる使い方ができることはわかったので、今後も使えそうな場面では使っていこうと考えています。

とはいえ、やはりユースケースと一緒に使うとより力を発揮するため、ゆくゆくはユースケースの記述や分析に慣れていきたいと思っています。

おわりに

書籍を社内勉強会で読んだという話を最初にしましたが、これは本当に偶然で、すぐに実践の機会が来るとは思っていませんでした。一エンジニアとして、普段から知識の習得や情報収集をしておいて手段という手札を増やしておくことがどれほど大切か、ということを改めて学ぶ機会となりました。

『ユースケース駆動開発実践ガイド』はとても良い本です。が、最初から全部読んで理解しようとすると結構辛いので、不要と思った部分はバッサリ読み飛ばし、必要になったら戻ってくるという読み方をお勧めします(社内読書会では実際そのようにして最後まで読みました)。

今回は、ロバストネス図をBill Oneの環境や状況に応じて活用してみたお話でした。他の開発現場でも役立つ場面があると思いますので、参考になれば幸いです。

*1:社内制度についてはこちらもご覧ください。

*2:普段の開発では、Bill Oneのエンジニアはバックエンドとフロントエンドの区別なく担当する

*3:仕訳の貸借合計金額が一致しない、勘定科目が選択されていない等

© Sansan, Inc.