以下UI/UXの設計の話なのですが、アニメーションなどの動きや見栄えの話ではありません。これまでの経験上、実装後に顧客からそんなつもりではなかったと言われて、外部設計がやり直しになった反省を踏まえて、「取りあえずこれだけはヒアリングしておけ!」のリストです。
ヒアリングリスト
1.「ボタン」を使える/使えないを制御する時は、次の2つの内どちらを使いますか?
1.1.「ボタン」を「表示する/表示しない」ことで、「ボタン」を「使える/使えない」を実現する。
1.2.「ボタン」を「Enable/Disable」にすることで、「ボタン」を「使える/使えない」を実現する。
2.「コンボボックス」や「リストボックス」、「グリッド」の中に一覧する要素は「データベース」の内容を
単純に全部見せますか?それとも、アクセスしている人の権限の範囲で見せますか?
3.「コンボボックス」や「リストボックス」の中に一覧する要素は「○○マスタ」から取得するとして、
将来「○○マスタ」のとあるレコードが不要になったら、次の2つの内どちらにしますか?
3.1.その「要素」を「表示する/表示しない」することで、「要素」を「使える/使えない」を実現する。
3.2.その「要素」を「Enable/Disable」することで、「要素」を「使える/使えない」を実現する。
4.アクセスしている人の権限で、データの特定の「カラム」を「使える/使えない」を制御する場合、
次の2つの内どちらを使いますか?
4.1.その「カラム」を「表示する/表示しない」することで、「カラム」を「使える/使えない」を実現する。
4.2.その「カラム」を「Enable/Disable」することで、「カラム」を「使える/使えない」を実現する。
#1.「ボタン」を使える/使えないを制御する時は、次の2つの内どちらを使いますか?
##1.1. 何故このヒアリングをするのか?
このヒアリングは、顧客の真意がどこにあるかを確認するための質問です。この真意を確認することができず、顧客の期待値と異なる結果となった苦い経験からのヒアリングポイントです。
初めて一緒に仕事をする顧客と会話するときには、この苦い経験も交えて話します。
「表示/非表示」だと状況によっては、ユーザの使い勝手が悪くなったり、「Enable/Disable」だと状況によっては、ボタンの存在すら教えたくなかったのに、それがバレてしまうといったこと起きるので、顧客側にもちゃんと理解してほいからです。
##1.2.苦い経験
ある顧客の場合、「○○権限を持っていない人はそのボタンを**使えないようにして欲しい」と言いました。
これを言葉の字面だけ見て、「使えないように」だから、「Enable/Disable**」で実装しようと考えて、外部設計書を書きました。
外部設計書には、画面レイアウトとして、ワイヤーフレーム図や実際にHTMLを書いてブラウザ表示画面キャプチャをまとめましたが、全ての権限の種類の数だけ画面のイメージを作るのは現実的な時間で作り切れなかったので、次のような表形式で設計書を整理して、顧客と合意していました。
NO | 画面要素表示名 | タイプ | 権限による制御 |
---|---|---|---|
01 | 「詳細参照」 | ボタン | 全てのユーザが利用できる。 |
02 | 「更新」 | ボタン | ○○権限を保持するユーザは「Enable」。 持たないユーザは「Disable」。 |
顧客の真意は、権限を持っていない人には、その「ボタン」の存在すらユーザに教えたくなかったのですが、「Enable/Disable」という記述が、自分の考えていることと一緒だと思って、特に追及もせずスルーしました。
その後、受け入れテストをしているなかで、顧客自身が思っていた真意と違っていることが発覚しました。
もしも、受け入れテストに参加しているメンバーに、その権限を持っていない人が参加していたら、そのボタンの存在がバレてしまうので、顧客と相当揉めることになるでしょう。
##1.3.では、いつも「ボタン」は「表示する/表示しない」で制御すればよいのか?
「Enable/Disable」にも良いところがあります。その「ボタン」を「Disable」にすることで、押すことはできないけれど、ボタンが「存在する」ことをユーザに知らしめることができます。
例えば、その時の画面のモード(参照モード/編集モード)や、データの状態によって「ボタン」の使える状態が変わる場合、ボタンがあらかじめ全て表示されていれば(もちろんモードや状態によってはボタンは**Disable**)、ユーザはこの画面で操作できることを事前に知ることができますが、もし「ボタン」が見えていないと、どういうことをしたらとか、どういう状態の時に「ボタン」が表示されるのか事前にはわからないからです。
##1.4.内部設計時の注意事項
上記のヒアリングはするとして、内部設計時に注意したいことは、「ボタン」の存在を知らしめたくないというのが顧客の真意だった場合、HTMLソースの表示をしたときにも、「ボタン」の存在がバレないようにしなければならないです。
#2.「コンボボックス」や「リストボックス」、「グリッド」の中に一覧する要素は「データベース」の内容を単純に全部見せますか?それとも、アクセスしている人の権限の範囲で見せますか?
これは、当然すぎるヒアリングです。ユーザのアクセス権限によって、当然見せて良いデータと見せてはいけないデータがあります。
#2.1.見落としてしまって、見えちゃいました
「グリッド」の中のデータに関しては、顧客もこちら側も結構気にするので、誰がどの範囲のデータを見てよいですか?と確認するのですが、見落としがちなのが、「コンボボックス」や「リストボックス」のデータです。
これらの画面コントロールは、入力補助的の役割であるため、顧客へのヒアリングが疎かになります。
データの見せる範囲をちゃんとヒアリングしなかったため、その後のDB論理設計で、「コンボボックス」や「リストボックス」に表示するテーブルの設計をする時には、汎用的に使える設計にしようと努力をしたのですが、データの表示範囲に関する工夫をしていませんでした。
その後、顧客の受け入れテストで「見えてはいけないものが見えている。どうしてくれるんだ!」となります。
#2.2.どんなに急いでもそんなにすぐに直せない
DB論理設計に、データ表示範囲に関する工夫など一切していなかったので、ユーザがアクセスできるデータ範囲を後付けで入れるのは難しいです。後から、コンボボックスマスタのコード値とユーザの権限とトランザクションを関連付ける何らかのモノを組み入れるのは、中々できないです。
#2.3.後で後悔するくらいなら初めから聞く
ですので、意識的にこれらの画面コントロールの要素の見せる範囲を聞くようにします。
この話を意識的にできるようになると、その後のDB論理設計で、ユーザへのデータ表示範囲を考慮したテーブル設計になっていきます。
#2.4.「コンボボックス」や「リストボックス」、「グリッド」の中に一覧する要素の持ち方に関して
こちらは、あまり顧客確認する話ではないですが、上記のヒアリング結果を受けて、内部設計をする際のポイントです。
秘匿性の高いデータの場合は、HTMLソースの表示をしたとしても見えないようにしなければなりません。
#3.「コンボボックス」や「リストボックス」の中に一覧する要素は「○○マスタ」から取得するとして、将来「○○マスタ」のとあるレコードが不要になったら、次の2つの内どちらにしますか?
マスタのとあるレコードが不要となった時の扱いは色々と問題が潜んでいます。
RDB上で、マスタとトランザクションの間で参照整合性制約を張っていれば(CASCADE DELETEはしない)、マスタからレコードが削除しようとしても、そのレコードを使っているトランザクションが存在していたら制約例外でできません。
しかし、「コンボボックス」や「リストボックス」に表示するマスタは、色々と画面向けの汎用的な作りこみをしたテーブルにしていて、トランザクションテーブルと参照整合性制約が張れないことがあります。この場合、アプリケーションで不整合が起きないようにしなければならないのですが、不幸な出来事が起こりがちです。
顧客と会話するときに、「コンボボックス」や「リストボックス」は軽く見られがちです。我々も安易に考えていて、将来「○○マスタ」のとあるレコードが不要になった時は、「単純にそのレコードを消せばいいんでしょ」位の意識だったりします。しかし、下記のような不幸な出来事が起きることをちゃんと話すと、皆「はっ」となって真剣な顔になります。ということで、このヒアリングをするときは、必ず下記のような不幸な出来事も交えてヒアリングします。
##3.1.不幸な出来事
アプリケーションが安定稼働して数年たった後、「コンボボックスマスタ」テーブルの「A項目」用のコンボボックスのコード値(10)が不要になりました。顧客からは、間違ってそのコードを使われると困るので、**すぐに使えないようにしてほしい**と依頼がありました。
依頼に従い「コンボボックスマスタ」テーブルから、「A項目」用の該当のコード値(10)のレコードを削除しました。
その後、顧客からの問い合わせで、とあるトランザクションデータの「B項目」だけを編集したはずなのに、全然関係ない「A項目」が「値の指定なしのnull」になっていると連絡がありました。
原因を調べてみれば当然で、「コンボボックスマスタ」の「A項目」用のコンボボックスからコード値(10)のレコードを削除してしまったからです。
トランザクションを編集モードで開くために、「A項目」の「コンボボックス」を作るのですが、コード値(10)が削除されたので、「コンボボックス」には編集されません。
一方でトランザクションの「A項目」では、コード値は「10」でした。このトランザクションを編集モードで開くと、コンボボックスにはコード値(10)が存在しないため、「null」となりました。
##3.2.これは、根深い問題です。
顧客の要望では、間違ってそのコードを使われるのが困るので、**すぐに使えないようにしてほしい**なのですが、既存のトランザクションがあるために、「コンボボックスマスタ」から該当のコード値を削除できません。削除してしまうと、上記のように既存のトランザクションが「null」になってしまうからです。
あちらを立てれば、こちらが立たずです。どうしよう。
受け入れテスト時点で、このような問題が発生したらまだマシですが、運用保守フェーズに入ってから発生したとしたら血の気が失せます。コンボボックスにしている項目はマスタから値を取得するので、コード値のチェックや必須チェックなどのValidationは指定していないと思います。このため、上記の例のような「B項目」を編集したのに、意図しない「A項目」が「null」になったことを検知するのが遅れます。
さらに、問題なのは、「null」になったのが、「値の指定なし」をユーザが意図的に指定したのか、それとも意図せず「null」になったのかを調べるのがかなり難しいからです。
トランザクションを全て履歴で保存していれば、何時から「null」に変化したかわかるので、マスタからコード値を削除した日付との関係を整理すれば、影響のあったトランザクションを調べられます。
しかし、トランザクションが更新の都度、上書きされるような設計だった場合は、更新したユーザ一人一人に、これは意図した更新かどうか聞きまわることになり、現実的ではありません。
##3.3.血の気が失せる前に外部設計時に決めておく。
血の気が失せるようなことになる前に、外部設計時のちょっとヒアリングしておけば済むので、上記のヒアリングをしましょう。
それから、次の2点もついでに設計に仕込んでおきましょう。
①マスタの物理削除はダメ。論理削除の仕組みを考えておく。
「削除フラグ」や、「レコードの適用終了時期」などのカラムを設けて、マスタのレコードを論理削除できるようにしておく。
マスタの論理削除ができてしまえば、あとは、それを「表示/非表示」するのか、「Enable/Disable」で行くのか決めればよいです。
②トランザクションは履歴で保持しよう。
トランザクション件数次第ではありますが、イベントの都度履歴で保持しましょう。
#4.アクセスしている人の権限で、データの特定の「カラム」を「使える/使えない」を制御する場合、次の2つの内どちらを使いますか?
これは、上記2.のヒアリングポイントの「カラム」バージョンのヒアリングです。これも当然すぎるヒアリングです。ユーザのアクセス権限によって、当然見せて良いデータと見せてはいけないデータがあります。
##4.1.内部設計時の注意事項
上記のヒアリングはするとして、内部設計時に注意したいことは、「カラム」の存在を知らしめたくないというのが顧客の真意だった場合、HTMLソースの表示をしたときにも、「カラム」の存在がバレないようにしなければならないです。