実践 ICONIXプロセス : 入力データの妥当性検証の発見と詳細定義

ICONIXプロセスでは、入力データの妥当性検証を、ユースケースモデリングの「代替コース」として発見し、記述する。

記述例:

代替コース
電子メールアドレスの形式が間違っていた場合:
「メールアドレスの形式が正しくありません」メッセージを表示する。

この代替コースを、要求レビューを経て、ロバストネス分析で、ロバストネス図の「コントロール」として描き、テストモデルにテストケースとして追加し、詳細設計のシーケンス図でメソッドに割当る。

大きな流れは、こうなんだけど、e-mail アドレスの詳細な仕様は、どこに、いつ、どうやって記述するのだろう?

最初はユースケースに
・代替コースの名前
・ユーザに表示するメッセージ(の中核)
程度を記述する。(基本事項だけ記述)

「 e-mail アドレスの正しい形式 」は、詳細すぎて、ここには書けない。
メッセージの内容も、画面では、より親切なガイドや説明を出したいかもしれない。

ICONIXプロセスでは、このような詳細情報は、「ユースケース」に添付する参考資料「補足仕様」として扱う。 モデリングツールに Enterprise Architect を使っていれば、補足仕様はノートや添付ファイルとして追加する。

ICONIXプロセスは、参考資料(補足仕様)の例として、この他に
・画面のモックアップ(実物大の模型:画面項目は実物と同じ詳細さ)
・データモデル (テーブルのカラム定義)
をあげている。

初期のユースケース記述は、手書きの画面紙芝居から出発する。

・画面モックアップ
・補足仕様書
・データモデル
などを作りながら詳細仕様をユースケースモデルに追加していく。

ユースケースモデルに補足仕様を追加したら、その補足仕様で発見・確認できた属性をドメインモデルにも並行して追加する。

ユースケースモデルとドメインモデルの同期をいつも重視するのが ICONIX流。

実践 ユースケースモデリング 代替コース 入力バリデーション

ICONIXプロセスでは、ユースケースモデリングで徹底的に「代替コース」(雨の日のシナリオ)を発見することを強調しています。
「代替コース」の多くは、入力データの妥当性検証(バリデーション : validation ) です。
入力バリデーションの対象を見つけ、丁寧に実装すれば、安心して使える良いソフトウェアが作れる。

入力データの妥当性検証は、おもなパータンを一度マスターしてしまえば、代替コースの発見、実装、テストがとても楽ができる。
いろいろなユースケースに登場するので、開発チームで、基本パターンを整理し、モデリングや実装の約束ごとをきめておけば、無駄な作業が減らせる。システムの振る舞いが一貫したものになり、利用者にわかりやすいソフトウェアになる。

Webアプリケーションの入力バリデーション

フレームワークが基本パターンを用意しているので、最低限、そのパターンはマスターしましょう。

Struts の Validator
Ruby on Rails の validates_*

が参考になります。
(実装技術として使わなくても、バリデーションの基本パターンの理解に役に立ちます)

データベース制約

入力データの妥当性検証は、ドメインモデルのビジネスロジック(ビジネスルール)を画面で表現したものです。

このビジネスロジックは、データベースでもカラム定義や「制約」として実装します。

カラム定義はデータ型とサイズを定義する。いちおうのドメイン(問題領域)の知識。

より豊かなドメインの知識は、データベース制約を使って実装できる。
データベース制約を理解すると、ドメインの知識の発見に役に立ちます。ユースケースモデリングの「代替コース」の発見のネタになります。

データベース制約の種類は、
・一意制約
・Not Null 制約(必須)
・主キー制約
・外部キー(参照)制約
・検査(Chaeck)制約 フォーマット検査や範囲検査
ですね。

PostgreSQL 制約
Oracle 制約

が参考になります。

XML スキーマの型チェック

XMLは、ドメインモデルを テキストで実装する技術ですね。
文書定義が DTD から XML スキーマ に発展して、データの妥当性検証ルールの記述能力が格段に向上しました。

XMLの妥当性検証は「型の定義」と「型の制限(Restriction)」という考え方で統一しています。
XMLのデータ妥当性検証は、画面からの入力データの妥当性検証と目的は同じですから、とても参考になります。

XML Schema 型チェックと制限 ( Restriction )


Webアプリケーションのフレームワークのバリデーションのパターン、データベース制約、XMLスキーマの型の制限、この三つをマスターすれば、ユースケースモデリングの「代替コース」の発見がとても楽になるし、定義内容が洗練されます。

実践 ユースケースモデリング 代替コース 不一致、重複

よくある代替コースの続き。

不一致

入力したデータが、既存のデータと一致することが必要、というケース。代替コースは「既存データと一致しなかった時:」。

たとえば、注文番号での問い合わせとか、登録炭メールアドレスと一致しなきゃいけない時とかですね。
データベースのテーブルだと参照制約。

フリーワードの検索などで、一致するものがない時もこのケースかなあ?
Not Found ケースといえば、どちらも Not Found ケースですね。

ちょっと特殊なケースとして、パスワードやメールアドレスの登録時に、同じものを2度入力する時の「不一致ケース」。

うーん。 参照制約系、Not Found 系、2度入力系、それぞれ別パターンかな。

重複 (一意妥当性)

入力データが一意でなければいけない。既存データと重複してはいけない場合。
代替コースは「入力データが既存データと重複した時:」。

新規登録時に、登録IDなどでチェックしますね。

データベースの一意制約ですね。

実践 ユースケースモデリング 代替コース 入力検証 不一致、重複

ユースケースの代替コースの多くは、入力の妥当性検証。
代表的なのは「必須」「型」「長さ」「範囲」の4つ。できれば(数字や文字列という基本型ではなく)ドメインオブジェクトとして定義して、ユースケースの妥当性検証は「型チェック」中心でやりたい、と書いてきました。

書きながら発見したことを忘れないうちに、項目だけ書き留めておきます。

・何かに一致する、という妥当性がある。
・重複していない(一意)という妥当性がある。

・「型の妥当性検証」としてしまった場合、画面の具体的なメッセージ内容はどこで定義する?

実践 ユースケースモデリング 代替コース 入力検証 範囲・長さ

ユースケース記述の代替コース。入力データの妥当性検証で、型の妥当性がOKなら、次は、文字列の長さ、値の範囲の妥当性を検証する。

文字列の長さ

文字列(String)型は、汎用的なデータ型。
型の妥当性検査で書いたように、e-Mail アドレスや電話番号は、型として妥当性検証されているので「文字列の長さチェック」の対象外です。

つまり、文字列の長さチェックは、「文字列(String)型」という汎用の入れ物を使った場合のチェック。ほんとうは、このチェックは少ないほうが良いんだと思う。つまり、「商品名称」も文字列データとしてではなく、意味のあるドメインオブジェクトとして、型チェックの一部として、文字数をチェックする。

実際には、私たちも、文字列型で処理して、長さチェックをやっちゃっているんですけどね。

文字列の長さは、論理的な正しいルールを決定できないことが多い。
例えば「商品名称」は、何文字以上、何文字以下であるべきか、決定できますか?

「妥当な長さ」というのは、常識的なところを誰かが決めてしまえばそれでよい。
字数の議論はあまり意味がなく、決まっていること、それも時間をかけずにとっとと決めてしまうことが実践的だと思います。

私たちは、入力の説明の時に「N文字以内で」と書いた時に違和感がなければ、それで良いという感じで適当(?)に決めてしまいます。 商品名称が100文字以内(最大100文字)というのは私はかなり違和感があります。 そんなに長い商品名はへんだと思う。みなさんはどうでしょう?

最初文字数も1文字以上というのは違和感がありますが、結構1文字以上(つまり空白はだめ)にしているかな?

値の範囲

値の範囲は、ビジネスルールとして厳密に確認・定義すべきことが多い。○○以上と◇◇以下という定義ですね。

数値型や日付け型という汎用のデータ型で扱う場合には単独のロジックを書くけど、「予定日」というオブジェクトは、明日から1年以内の値だけで、作成できる、というルールは、「予定日」クラスに実装して、妥当性検査としては「型チェック」で良いのではと思っています。

ユースケース記述では、代替コースは、「型が妥当でなかった場合:」というように。

まあこうやって、型のチェックにいろいろロジックをカプセル化していけば、ユースケースの代替コース記述は簡単になりますね。

もちろん、型の定義を詳細にやる必要があるわけですが、それは、ユースケースモデリングではなく、ドメインモデリングからクラス設計の流れ、つまり静的モデリングのほうがやっていく。

ユースケース記述では、入力したら「妥当性検証」があることを代替コースとして洗い出し、妥当でなかった場合のユーザとシステムの対話モデルを明確にすることに集中する。

妥当性の詳細は、ユースケースの検討ではなく、ドメインモデル(クラス設計)の課題として扱う、というのが良いのでは、と考えています。
(もうちょっと実践してみて、それが良さそうか検証したいと思います。)

実践 ユースケースモデリング 代替コース 入力データの妥当性検証

ユースケースの代替コースの多くは、入力データの妥当性検証(バリデーション) に関係したものです。

入力データの妥当性検証項目:

・必須チェック
・型チェック(形式チェック)
・長さチェック
・範囲チェック

が主なものですね。

型チェック(形式チェック)

数値項目

例えば、数値項目であれば、正しく数値として処理できる形式で入力されているかのチェックです。
3桁区切りのカンマ入力、正負の記号、全角数字、K(1000)やM(1000000)の使用、通貨記号や数量単位 ( グラム、センチメートル ... ) など、単純に半角の数字のみではなく、一般的なな表記は妥当としたいものです。
コピー&ペーストで入力されることもあるので、前後の空白なども利用者に優しく扱いたいですね。

日付け項目

日付けになると、さらにいろいろな入力形式があります。
YYYY-MM-DD 以外は全てだめ、半角数字のみ、というような厳しい妥当性検査はもちろんやるべきではない。 数字が一つだけだったら、当年・当月のその日または、翌月のその日とか、翌日とか翌週を簡単に指定できたりとかいろいろなやさしさが考えられる。

実装時には、カレンダでクリックを好む人がいますが、個人的には、文字入力のほうがすきです。
ドロップダウンで、1から31を選ぶというのも、良いインタフェースとは思えない。

文字列の場合は、文字種の制限とかがありそうですね。ヨミガナはもちろんカナだけだろうし。

入力データはすべて文字列ですが、数値項目や日付け項目は内部的には数値型や日付型のオブジェクトにする必要がある。データバインディングですね。

ここらへんの基本的な入力データの妥当性検証とデータバインディングの仕組みは、汎用ツールを用意しておきましょう。
実装面で汎用ツールがあれば、ユースケースの代替コースの記述内容も単純化(標準化)できますね。
代替コースで、「型チェック」の詳細を考えずに「型が妥当でなかった場合:」というお約束コースを書くだけで済ませる。

よりアプリケーションよりの型

郵便番号、電話番号、クレジットカード番号、電子メールアドレス、ホームページURL、...など、基本データ型以外に、さまざまな型とその形式妥当性のルールがあります。

こういうものも、ユースケース記述の代替コースとして詳細に仕様を書くのではなく、ドメインオブジェクト側の仕様として記述すべきだと思います。

ユースケースでは、単に「妥当な型でなかった場合:」で済ませる。

ユースケースを書いているときは、
・画面とユーザのアクション
・システムがやるべきこと
・起きる可能性がある例外の場面(代替コース)
を「項目」として「全て」を見つけることを最も重視する。

「全て」を見つけることに集中するには、型チェックの詳細は(今は)やらないほうが良い。

「妥当な型でなかった:」という代替コース自体は、きちんと記述しましょう。実際に起きることだし、その時、ユーザとシステムでどのような相互作用を想定するかを関係者で共通理解にするために。

実践 ユースケースモデリング 代替コース システムエラー

システムエラー、例えば、データベース接続に失敗とか、ランタイムの例外は、個別のユースケースには書かないことにしました。

これらのエラーは、利用者がやり直して復旧することはできません。「サポートセンターに連絡してください」画面くらいですかね。

実装も、個々の画面で、状態をチェックして個別のエラー画面の表示するのではなく、Web アプリケーションのフレームワークやアプリケーションサーバーに任せてしまう。例外を最上位まで伝播させると、最後は アプリケーションサーバーが例外をキャッチして、既定のページを表示してくれる。

こういう「地震の日」みたいな可能性と処理は、個別のユースケースに書く内容ではないですよね。

「もう一回やってみてもらう」ことに価値がある場面があったら、ユーザとの相互作用(インターアクション)なので、ユースケースの代替コースとして書こう、という話をしていますが、まだ具体例はでていません。

代替コースの発生時に場面に応じた情報を表示して、かつ利用者がシステムとの対話を続けることができる場合は、それぞれのユースケースとして記述する。

システムエラーのように汎用のエラー表示になってしまい、利用者がシステムとの対話を続けられない状況は、ユースケース記述の対象外。

実践 ユースケースモデリング 代替コース

ユースケースモデリングでは、最初に基本コースを記述する。その基本コースの1ステップづつ確認しながら、可能性のある例外や特別のケースを発見していく。

これが「代替コース」。

基本コースは、晴れの日のシナリオ。
代替コースは、雨の日のシナリオ。

ユースケース記述で代替コースを発見し、その時、システムはどう振舞うべきかの記述がしっかりしているほど、良いソフトウエアになる。

代替コースのモレ、代替コース発生時の乱暴なシステムの応答は、ソフトウェアの評価をがた落ちにする。

でも、代替コースの発見と記述は、たいへんな作業だし、また人によって考え方や書き方がばらつく。

代替コースについては、開発チームでいくつか取り決めをしておくと、代替コースの発見や記述が楽になり、また、記述レベルや内容のムラを減らすことができる。

実際に私たちがやっているユースケースモデリングで、でてきた疑問や自分たち流の取り決めをそれぞれ別の記事で紹介します。

・システムエラー(実行時例外)の扱い
・入力内容の検証と、不正だった時の扱い
・ユースケースでの記述の粒度

まだ、試行錯誤中ですが、少なくとも、何も取り決めがないよりは状況は改善した実績はあります。

実践 ユースケースモデリング ユースケース図は全体像

ユースケース図は、作ろうとしているシステムは、
・誰が使うか
・どんな利用場面があるか
を図で表したものです。

パッケージを使って、整理することは重要。全体が見やすくなります。

アクタ(人の形のアイコン)とユースケース(楕円)とを線で接続したり、ステレオタイプや汎化関係のモデリングは時間の無駄。
私自身は、こういうモデリング作業が役に立つソフトウェアを作ることに効果があった経験がありません。
余計な詳細モデリングをしないユースケース図は、ユーザ側の関係者にも分かりやすいというメリットは感じています。

ユースケース図は、作るもの、修正するのも簡単です。ですから、ユースケースを追加したり、アクタを発見したり、パッケージを再編成したりすぐできる。
システムの全体像自体もプロジェクトを通じて変化していく。 ユースケース図には、今回の対象外のものも含んでいても良い。
もちろん、全体をわかりやすく保つこと、中核(現在の焦点)がどこにあるかを示すことは重要です。

広域地図と、現在地表示ですね。まあ、地図と違って、全体像がどんどん変わっていきますが。

ひとつひとつのユースケースは、初期の記述、レビュー、ロバストネス分析と予備設計レビュー、シーケンス図による詳細設計と設計レビュー、実装とコードレビュー、テスト、とかなりの作業が発生します。

どのユースケースから取り掛かるかの順番決めはとても重要。時間と人という貴重なリソースをつぎ込むわけですから。

実践 ユースケースモデリング ユースケース図はメニュー設計

ICONIXプロセスでは、個々のユースケースを書き始めるまえに、ユースケース図でアクターとユースケースを洗い出していく。ユースケースは、すぐ増えるので扱いやすいようにパッケージ図を使って、整理(組織化)する。

このユースケース図で描いた構造を、実装すると画面上では、たとえば階層メニュー(メニューツリー)になる。アクターごとに別のトップ画面があるサービスなら、ユースケース図のパッケージとトップ画面が対応する。

ユースケースモデリングの最初のステップであるユースケース図作成が、そのままメニューの実装につながる。

ICONIXプロセスは、ここ以外にメニューの詳細設計や検討をする手順はでてきません。ユースケース図とそのパッケージ構成が、そのままメニュー構成、トップ画面構成になります。

その視点で、ユースケース図のレビューをやると、いろいろ課題や疑問がみつかります。あるいは画面プロトタイプの早い段階で、ユースケース図の構造と実際のメニュー階層ととが一致していることを確認する。

ユースケースの構成と、画面のメニュー構成に、用語・グルーピング・順番などの不一致があるのは、問題領域の理解がずれている注意信号です。敏感にキャッチして、早い段階で、不一致をつぶしましょう。


calendar
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< March 2024 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM