こんにちは。スマートバンクで iOS / Android エンジニアをしている nakamuuu です。
4月に開催したオンラインイベント 『B/43 TECH TALK〜「お金の使いすぎ」を防ぐ新しい家計管理機能開発の裏話〜』 では、直近リリースした新機能の開発プロセスの裏側を紹介しました。職種幅広くたくさんの方にご参加いただき、ありがとうございました 🙌
このイベントで私からは 「複雑な構成要素を持つUIとの向き合い方 〜新・支出グラフでの実例〜」 のタイトルで、 "複雑性の高いUIの構築における考え方" をテーマに簡単なLTをさせていただきました。今回のエントリーでは、イベントでお話しした内容を抜粋する形で簡単に触れていこうと思います。
"複雑な構成要素" を持つ支出グラフ
3月下旬にリリースした「お金の使いすぎを防ぐ新機能」では大きなアピールポイントとして "支出グラフ" を推し出しています。
これまでも B/43 には毎月の支出を把握する “まとめ画面” があり、全体の支出をカテゴリごとの内訳で区切る円グラフが主体の画面となっていました。これを今回のアップデートで “支出画面” としてリニューアルしました。
この “支出画面” で新たに実装した折れ線グラフが今回の話の題材となります。
新しく実装した支出グラフの大きな特徴が "UIを構成する要素が多い" ことです。また、時間軸や支出の状況、ユーザーの操作によっても表示が変わりうるところもポイントとなります。
そのような特徴を持つ支出グラフを題材として、以下の3つのセクションに区切って「設計フェーズにおける “複雑な構成要素を持つUI” との向き合い方」を考えていきます。
- 1 : 構成要素の定義 : 構成要素を分解し、各要素の呼称や振る舞いを定義する
- 2 : データソースの設計 : 表示に要する情報を網羅的に整理し、データソースを設計する
- 3 : インタラクションの整理 : ユーザー操作や表示状態を洗い出し、介在する状態を整理する
1 : 構成要素の定義
繰り返しになりますが、新しい支出グラフはUIを構成する要素が多いのが特徴です。初手のアプローチとしてはベタですが、多様な構成要素に対する命名を進めました。設計をチーム内に共有したり、 iOS と Android の間で仕様を擦り合わせる際にも言葉が揃ってないと誤った理解になりかねません。
そして、次に構成要素の単位で振る舞いを定めていきます。他の構成要素であったりデータへの依存が少なそうなところから進めると考えやすいです。今回の支出グラフでは座標平面の目盛りが依存箇所が少なかったので、「座標平面 → グラフ本体 → その他の付帯情報」の順で細かな仕様であったり振る舞いを詰めていきました。
例えば座標平面の日付の目盛りでは「日曜日の日付を抽出して表示する」、金額の目盛りでは「最大の支出額から上限値を決定する」など、構成要素単位での細かな仕様を定めていきます。
この過程ではそれぞれの構成要素で必要となる具体的なデータもイメージできてくることと思います。必要なデータをリストアップして、都合のよさそうなデータ構造が想像できてきたら、次のステップの「データソースの設計」へ入ります。
2 : データソースの設計
支出グラフには2つのデータの見せ方が存在していました。ヘッダー部分では特定の日付時点での支出額や残り予算など "日次のスナップショット" を示しています。一方でグラフ本体は集計期間の全体を通した支出額の "連続した推移" を示しています。
これを踏まえた上で、支出グラフで用いるデータを構造的に落とし込んでいきます。すると、日次で全ての情報を集約したスナップショットの集合とするか、グラフ単位で連続した推移を集約して表現するかの2つの案が出てきました。少し細かいところなので「2つのデータ構造で悩んでいたこと」だけ捉えていただければ問題ないです。
このように、複数のデータ構造のどれにするか悩んでいて決定打に欠ける場合、JSON上で暗黙的に生じうる規則を書き出すことをおすすめします。例えば「この値がnullならこっちの値もnullになる」、支出グラフの例では「開始日から終了日までの日付のデータが欠落しない」のようなものが暗黙的な規則です。
データベースからAPIやモバイルアプリの一連を通し、レスポンスに用いるJSONが暗黙的な制約であったりNullableな値が生じやすい "表現力が一番低い媒体" になりやすいと思います。JSONでいかに暗黙的な制約を少なくできるかは、データ構造をシンプルに保つために有用な判断材料であると考えています。
3 : インタラクションの整理
最後に "インタラクションの整理" として、ユーザー操作やそれに伴う表示に関する考慮をしていきます。
新しい支出グラフではグラフ上をドラッグすることで過去の支出の傾向を確認することができます。支出が目安よりオーバーしているところでは、札束が舞うようなパーティクルのエフェクトも発火しています。
グラフのドラッグ操作が影響を与える要素を並べてみます。まず、ドラックを行うとインジケータの位置が移動し、その日に決済したお店の名前が表示されます。また、ヘッダー部分もドラッグに合わせて支出額などの表示が切り替わります。そして、支出傾向に合わせたパーティクルの表示やスマートフォンが軽く振動するような Haptic Feedback も発火しています。
このように操作とそれが作用する先の表示を羅列した上で、 “操作” と “表示” の間に介在する Mutable な状態の抽出 が、インタラクションの整理において大事であると捉えています。今回の支出グラフで必要となる状態は “フォーカスされている日付” のみなので、この点では比較的シンプルな例となります。フォーカスされている日付に応じて、インジケータやヘッダーなどの表示が切り替わります。また “日付の変動” のタイミングに合わせて、パーティクルや Haptic Feedback が発火します。
“操作” と “表示” の間に介在する状態を考えておくと、SwiftUI や Jetpack Compose でのUIの実装方針も自ずと定まる部分があります。「何を状態として切り出すべきか」を設計のフェーズにおいて前もって考えておくことで、実装もスムーズに進められるのではないでしょうか。
まとめ
今回のイベントでは、私から支出グラフを題材に「設計フェーズにおける “複雑な構成要素を持つUI” との向き合い方」についてお話させていただきました。 "構成要素の定義" "データソースの設計" "インタラクションの整理" の3つのステップや考え方は、さまざまなUIの設計で流用できることと思います。
時間の都合や幅広い職種の方々にご参加いただいたこともあり、今回は具体の実装までは触れずにあくまでも考え方のプロセスを紹介しました。話をより実装者目線に寄せるのであれば、 "構成要素の定義" における命名でのコツや考え方を深掘れるかもしれません。 "データソースの設計" "インタラクションの整理" ではより iOS / Android のプラットフォームの機能、あるいは各プロダクトにおける設計指針と紐づけた思考もできるでしょう。
複雑な構成要素を持つUIとの向き合い方について考えを深められた際には、どこかのタイミングで改めて紹介させていただければと思っています。
スマートバンクでは一緒に B/43 を作り上げていくメンバーを募集しています!カジュアル面談も受け付けていますので、お気軽にご応募ください 🙌 smartbank.co.jp