UiState にドメインモデルをどこまで持たせるべきか考えた

結論 なぜそう考えたのか ID は比較的「安定した概念」 本当に危険なのは「変化しやすいドメインモデル」 一方、ID は変化しにくい むしろ UI専用 ID を増やすデメリットもある 最近は「全部分離」が正義ではないと感じる まとめ Jetpack Compose で画面実装をしていると、よく悩むのが、 UiState にどこまでドメインモデルを持たせるべきか UI専用モデルをどこまで作るべきか という問題です。 最近、自分は Id の扱いについて考える機会がありました。 きっかけ たとえば、以下のような UiState があるとします。 data class UiState( val id: Id = Id.Unassigned, val name: String = "", ) { sealed interface Id { data object Unassigned : Id data class Assigned(val value: Int) : Id } } 一方で、ドメインモデル側にも、ほぼ同じ定義があります。 sealed interface PaymentId { data object Unassigned : PaymentId data class Assigned(val value: Int) : PaymentId } さらに、今後ほかの画面でも、 PaymentEditUiState.Id PaymentDetailUiState.Id PaymentListItemUiState.Id のような、似た ID 型が増えていく可能性がありました。 ...

2026年5月26日 · 2 分 · 奥田 智紘

Jetpack Compose Navigation のパラメータ指定の罠

すぐに思いつく実装 「新規作成 or 編集」を型で表現する なぜエラーになるのか 正しい設計:Navigation はプリミティブ型を渡す 重要なポイント Navigationの責務 UI の責務 一覧画面から「新規作成」と「編集」の両方に遷移するケースは、アプリ開発でよくあります。 例えば以下のような仕様です: リストのアイテムをタップ → 編集画面へ 「追加」ボタンをタップ → 新規作成画面へ 画面UIは同じ(内部の動作だけ異なる) すぐに思いつく実装 すぐに思いつく実装方法は以下ではないでしょうか? Navigation の定義は以下の通り NavHost( navController = navController, startDestination = startDestination, modifier = modifier, ) { // リスト画面 composable<ItemList> { PayeeListScreen( onClickAdd = { navController.navigate(RegisterItem(null)) }, onClickItem = { itemId -> navController.navigate(RegisterItem(itemId)) } ) } // 登録・編集画面 composable<RegisterItem> { backStackEntry -> val registerItem: RegisterItem = backStackEntry.toRoute() RegisterItemScreen( onClickNavigateUp = { navController.navigateUp() }, itemId = registerItem.id ) } Destination の定義は以下の通り ...

2026年3月22日 · 1 分 · 奥田 智紘

ワイヤーフレームからドメイン設計が進んだ話

はじめに ドメイン設計だけでは埋まらない違和感 ワイヤーフレームを作って起きた変化 1. ユーザーの行動が具体化される 2. 必要なデータと制約が見えてくる 3. ドメイン設計の「抜け」が露出する ワイヤーフレームは見た目のためではない まとめ おわりに はじめに 最近、アプリ開発の中で「ワイヤーフレーム」を使い始めたところ、思いがけずドメイン設計が大きく前進しました。 ワイヤーフレームとは、 Figma などを使って作る UI デザインの一種です。 ただし、色やフォントサイズなどの細かい UI にはこだわりません。 ボタンや入力欄であることがわかれば良いという程度のラフな UI デザインのことを言います。 もともとドメイン駆動で設計を進めていたのですが、どうしても「抜け」や「曖昧さ」が残る感覚があり、手応えが弱い状態が続いていました。 しかし、ワイヤーフレームを作り始めたことで、その状況が一変しました。 この記事では、 ワイヤーフレームがどのようにドメイン設計を補完し、加速させたのかを整理してみます。 ドメイン設計だけでは埋まらない違和感 ドメイン設計を進めていると、以下のような状態に陥ることがありました。 ユースケースはある程度整理されている エンティティや値オブジェクトも定義できている しかし「本当にこれで使えるのか?」という違和感がある つまり、構造はあるが、実感がない状態です。 このとき不足していたのは、「ユーザーがどう操作するか」という視点でした。 ワイヤーフレームを作って起きた変化 試しにワイヤーフレームを作り始めたところ、明確な変化がありました。 1. ユーザーの行動が具体化される ワイヤーフレームでは「画面上で何をするか」を考える必要があります。 どこで入力するのか どの順番で操作するのか 何を確定とみなすのか これにより、ユースケースが単なる文章ではなく、操作として具体化されました。 2. 必要なデータと制約が見えてくる 操作を具体的にすると、自然と以下が見えてきます。 この画面では何のデータが必要か この操作はどんな条件で許されるのか ここで重要なのが、 不変条件(インバリアント) です。 例えば、口座振替管理アプリなら、 支払い元は必ず 1 つである 振替は「元 → 先」の関係を持つ 不正な組み合わせは作れない など、これらはドメイン設計だけでも定義できますが、 ワイヤーフレーム上で「操作」として考えることで、一気に現実味を帯びます。 3. ドメイン設計の「抜け」が露出する ワイヤーフレームを作る中で、次のような気づきが頻発しました。 この状態、どうやって作る? この操作、どのユースケースに対応する? このデータ、どこに属する? つまり、ドメイン設計で曖昧だった部分が強制的に表に出てくるのです。 ...

2026年3月18日 · 1 分 · 奥田 智紘