UIデザインのモデリングで値オブジェクトを使う
オブジェクト指向UIデザイン
UIデザインをする際に画面やコンポーネントをオブジェクトとして捉えOOUI(オブジェクト指向UI)の様にモデリングを踏まえてデザインすることが一般化してきています。
しかし、そうやって定義されるオブジェクトが持つ属性の値はFigmaなどのデザインツールのプロパティ(Component Propertiesなど)では「文字列」「数列」「真偽値」といったプログラミングの型付けでいうところの「プリミティブ型(原始的な・根源となる型)」やURLやファイルパスにとどまっています。
プリミティブ型で構成されたオブジェクトの何が問題かというと、そのオブジェクトの正しさを測る場合にただの文字列や数列だけでは値が本当に正しいものか判断がしにくいところにあります。
オブジェクトに属する値もオブジェクトとして捉える
例えば、年齢。年齢を扱うオブジェクトがあった場合はOOUIの場合は数列型になると思います。
しかし「年齢は0以上の整数」です。数列は負の値(例: -1)も小数点(例: 1.0)も全て含まれます。-1歳も0.1歳も基本的には年齢のルールから逸脱します。
この様に値にはそれぞれ「その値が成立するための制約」が存在し、オブジェクトに属するそれぞれの値がその制約を全て満たしてはじめて「正しいオブジェクト」と評価することができます。そういった意味ではプリミティブ型でのオブジェクトの表現はまだまだ抽象的であり具体性に欠ける状態ということになります。
オブジェクトを定義することはその対象になるモノの性質・制約などを明らかにする行為です。値は対象となるモノの性質の一つです。この値も同様にオブジェクトとして定義することで値の属するオブジェクトをより具体的に定義できることになると考えられます。
この考えはオブジェクト指向プログラミングやドメイン(領域)駆動設計では「値オブジェクト(Value Object)」と呼びれています。
UIデザインにもこの値オブジェクトの定義までやった方がより具体性の高いデザインやその工程でのコミュニケーションが捗るのではとと思いこの記事を書くことにしました。
まずプリミティブ型でモデリングしてみる
値オブジェクトが具体的にどういうものかまだ抽象的なので例を踏まえてみます。
例えば、ユーザの連絡先というオブジェクトを定義して考え、ここでは事業の都合上ユーザと次の方法で連絡を取る必要があるとします。
- メールアドレス
- 電話番号
これをモデリングすると以下のように定義できるとします。
UserContactInformation
例)ユーザの連絡先 属性
属性名(ja) | 属性名(en) | 型 | 必須か? | 初期値 |
---|---|---|---|---|
メールアドレス | string |
yes | なし | |
電話番号 | phoneNumber | string |
yes | なし |
メールでの連絡 | emailContact | boolen |
no | false |
電話での連絡 | phoneContact | boolen |
no | false |
振る舞い
- 登録している連絡先を確認する
- 連絡先(電話番号・メールアドレス)を新たに登録する
- 連絡先のメールアドレスを変更する
- 連絡先の電話番号を変更する
- 連絡先のメールアドレスに連絡をとる
- メールは連絡の有無に関わらず登録しておいてもらいたい
- 連絡先の電話番号で連絡をとる
- 電話番号は連絡の有無に関わらず登録しておいてもらいたい
デザインに値を当てはめてみる
上のオブジェクトモデリングから次の連絡先カードコンポーネントをデザインしてみました。
ユーザの連絡先(登録している連絡先を確認する)
プリミティブ型のゆるさ
上の連絡先カードコンポーネントは特に問題がなさそうに見えます。しかし、モデリングを踏まえるとこのオブジェクトだとメールアドレスも電話番号も string
つまり文字列型で扱われことになります。
表示される際は文字列なのでデザインツール上では次の3つの様にメールアドレスとして成り立たない値でも全て文字列なので間違いではないとされてしまいます(まぁ実際はこんなの定義するまでもないことでしょうけど)。
hoge[at]moge.com
ほげ@もげ.com
ほげもげ
デザイン上は誤った値でも表示できてしまう。
この様にデザインデータ上でやりとりされる限りではデザイナーは値の正当性について深く考えることはないと思います。というかそれはエンジニアの仕事でデザイナーが考えることではないという空気もあります。
今は随分減ってきていると信じたいですが、文言が決まっていない・ユーザの入力により内容が変わる場合に「ここにメールアドレスが入ります」だとか「◯◯◯◯◯◯◯◯」「ダミーダミーダミー」みたいな文字列を使うデザイナーがいます。オブジェクト指向でUIデザインするならおそらくこのダミー文字列を使うことはないと思うのでこれは最悪の例ですが、値の性質や制約の定義がないまま進めるのはダミー文字列使うのとあまり違いはないのかなと思いますし、以下の様な弊害も生まれかねません。
- どんな値が入ってくるのかわからないのに余分に文字数や文字種を許容するデザインになる
- 表示する際のラベルの文言が不適切な表現になる
- デザインデータを見て実装する"画面駆動"な開発[1]の場合はヴァリデーションはエンジニアが空気を読んで実装する
値を定義する
まずはメールアドレスを例にして値の定義をしてみます。
メールアドレスはこの場合特にビジネス的な制約もないので一般的な定義がそのまま扱えそうです[2]。とりあえずWikipedia(が正しいとは限らないですがこの記事は例なのでWikipediaから引用します)を参考にすると…
メールアドレス(英語: Electronic mail address)、Eメールアドレス(イーメールアドレス、英語: email address, e-mail address)とは、電子メールにおける送信先や発信元を表す。
引用: https://ja.wikipedia.org/wiki/メールアドレス
メールアドレスの形式は主に ローカル部@ドメイン
という形式であり、使用できる文字種も制限があります。日本語ドメインを許可したりしなかったりというケースもあるのでそこはサービス次第ですが、この一般的な形式を踏襲すれば先ほど入力のあった以下の値は正しくないメールアドレスとして評価されます。
入力されたメールアドレス | 正しいか? | 理由 |
---|---|---|
hoge@moge.com |
正しい | メールアドレスの要件を満たしている |
hoge[at]moge.com |
正しくない | @がない |
ほげ@もげ.com |
正しくない | 日本語ドメインを許可した場合は要件を満たしているが ローカル部が日本語 |
ほげもげ |
正しくない | @がない、ドメインの形式が間違っている |
これらをヒントにしたり、値そのもののルールを
Email
メールアドレス 属性名(ja) | 属性名(en) |
---|---|
アドレス | address |
制約と性質
-
ローカル部@ドメイン
という@で連結された文字列形式 - 文字数は全部で255文字
- 日本語ドメインは受け付ける
- ローカル部は英数文字と使用許可されている文字種のみ
- 次の文字種が使用可能
!#$%&'*+-/=?^_`{|}~.
+ 半角英数文字 - etc...(全部書くと大変なので省略)
こんな感じで考えると当然電話番号もただの文字列ではないので定義できそうです。
また、メールでの連絡と電話での連絡という属性も「連絡の許可」という共通しているので値オブジェクトとして定義できそうです。もちろん「許可をするか」に対して true = する/false = しない
という真偽値でも表せるかもしれませんが、 Allow = 許可する | NotAllow = 許可しない
という許可という値オブジェクトを定義するとよりわかりやすくなります。
他の値も定義し、オブジェクトに紐づける
ここで定義したメールアドレスと電話番号・連絡の許可の値オブジェクトを定義して、ユーザの連絡先 UserContanctInfo
に反映してみます。
PhoneNumber
電話番号 このサービスでは海外ユーザも扱うため電話番号は国際番号を採用します。
属性名(ja) | 属性名(en) |
---|---|
国番号 | countryCode |
番号 | numberValue |
制約と性質
- 国番号
- 国番号一覧を参照
-
1-88299
の各国に割り当てられた番号 -
+
記号はデータとしては含めない- 代わりに国旗アイコンで表現する
- 番号
- 日本の
市外局番-市内局番-加入者番号
といった形式は国によってことなる- 各国のフォーマットに合わせる
- 日本の場合は
市外局番-市内局番-加入者番号
- 日本の場合は
- 国によっては番号の先頭に
0
をつけるケースもあるのでその場合は0
を付与する
- 各国のフォーマットに合わせる
- 表示する際はハイフン区切りは国番号に合わせて区切れる場合は区切る
- 日本の
ContactPermission
連絡の許可 属性名(ja) | 属性名(en) |
---|---|
許可の値 | permissionValue |
- 許可するかしないかの2種類の状態のみを扱う
- true/falseは真 or 偽でわかりにくいので以下に様にする
- 許可 = Allow
- 不許可 = NotAllow
- true/falseは真 or 偽でわかりにくいので以下に様にする
ユーザの連絡先を再定義
属性名(ja) | 属性名(en) | 型 | 必須か? | 初期値 |
---|---|---|---|---|
メールアドレス | Email |
yes | なし | |
電話番号 | phoneNumber | PhoneNumber |
yes | なし |
メールでの連絡 | emailContact | ContactPermission |
no | NotAllow |
電話での連絡 | phoneContact | ContactPermission |
no | NotAllow |
モデリングした結果、デザインを最適化する
入力とバリデーション
振る舞いを見てみると「登録する」「変更する」というユーザが入力するであろう振る舞いがあります。つまり、Form要素を使ったGUIなどからユーザが入力をしてこれらの情報を変更することが想定されます。
ユーザの連絡先(入力及び編集)
電話番号の入力
上の入力欄をここまでに作ったモデルを踏まえて見ると、電話番号の入力は国番号と各国の番号を入力するものかどうかわかりません。
電話番号入力を最適化
今回は国番号は国旗アイコンをセレクタで選ばせ、その都度各国の番号仕様に合わせてPlaceholderや補足の部分を変更する想定でデザインしました。
メールの入力でのエラー
振る舞いの中に「連絡先のメールアドレスにメールでお知らせを送る」とあります。
つまり、ここで入力されたメールアドレスが「送信できるメールアドレス」でなければ「正しいメールアドレス」と評価できず当然ながらメールは届きません。つまりメールの形式によるエラーが存在することがモデリングで見えてきます。
メールアドレスの形式のバリデーションはエンジニアの実装によります。しかし、どういったエラーが存在し、そのエラーに対して何をどうユーザに伝えるのかはUIデザイナーが考えることだと思います。そのエラーの最適化が不十分だとユーザビリティ評価はよくない結果を招きます。
エラーを伝えても何が問題かわかりにくい
つまり「メールアドレスは文字列」ではあるけど、メールアドレスとはなんであるかという「制約」の部分まで定義することでよりわかりやすいUIデザインへの遠い様で近道になると思います。いわゆる『神は細部に宿る』というやつです。
モデリングをどこでやるか?
ここまで話してきて「モデリングはどの過程でやるか?」という問題があると思います。
モデリングは一過的なものではないと思います。
各工程は一方通行ではなく、モデリングで俯瞰と仰視を繰り返し、小さく作りながらそこで見えてきたものをモデルへフィードバックしを繰り返しながらやることでモデルを蒸留していきます。
要求分析から要件定義の工程ではRDRA(Relationship Driven Requirement Analysis)、エンジニアの設計・実装の工程ではDDD(ドメイン駆動設計)などがあります。[3]
各工程・開発に携わるメンバー間でモデルが共有され続けることでデザイナーのモデリングもより正確性を高めることができるのではと考えます。
まとめ
値オブジェクトはオブジェクトをより詳しく紐解くための設計手法です。
UIデザインのモデリング工程にこの値オブジェクトの考えを取り込むことでより精度の高いUIデザインやコミュニケーションをとれたり、デザイナー要件定義や設計のプロセスから参加する意義ができたりします。
値オブジェクトを定義することで得られるもの
- モデルを構成する属性値の正しさを評価できる
- 値はどういうものか定義されることで、どう表示するべきかどうインタラクションを作るべきかの判断基準になる
- 値の制約を整理してからデザインすることでエラーに対して細かく定義することができる
- 開発メンバーとより深いコミュニケーションができる
オブジェクト指向なUIデザインの工程でも値オブジェクトまで定義できればこういうメリットがあるのかなと思いますし、そういうところまで話せるデザイナーが増えると個人的に嬉しいです。
Discussion