Android アプリは「UI 駆動・状態駆動」である

Android アプリ開発の現実を一言で表すなら、「UI と状態の変更がすべて」と言っても過言ではありません。

多くの仕様変更は、次のような形で現れます。

  • 画面に表示する項目が増える/減る
  • 表示条件が変わる
  • ローディングやエラーの出し方が変わる
  • 画面遷移の分岐が増える

つまり、変更の起点はほぼ常に UI にあります。

Web や業務系システムのように「ドメインロジックが主役で、UI はその結果を表示するだけ」という構造とは、前提が大きく異なります。Android では、UI と状態管理が設計の中心に座らざるを得ません。

この事実を無視して設計を始めると、あとで必ず歪みが生まれます。


変更理由の大半は「ビジネスロジック」ではない

DDD という言葉を聞くと、多くの人は「複雑なビジネスロジック」を思い浮かべます。しかし、実際の Android アプリ開発で頻発する変更理由は、それとは少し違います。

  • 文言の変更
  • 表示順の変更
  • UI の状態分岐の追加
  • API レスポンスの仕様変更への追従

これらは、いわゆる「ビジネスルールの変更」とは言いづらいものです。

それにもかかわらず、すべてをドメインロジックとして抽象化しようとすると、設計は一気に重くなります。結果として、「変更が楽になるはずの設計」が、逆に変更の足かせになります。

ここで重要なのは、すべての判断をドメインに集約しなくていい という認識です。


レイヤードアーキテクチャが破綻しやすい理由

多くの Android プロジェクトは、次のような構成から始まります。

  • UI(View / Compose)
  • ViewModel
  • UseCase
  • Repository
  • DataSource

一見すると、責務がきれいに分離されているように見えます。しかし、プロジェクトが成長するにつれて、次のような問題が表面化します。

  • UseCase が単なる中継層になる
  • ViewModel が肥大化する
  • Repository に判断ロジックが混入する

これは、設計が悪いから起きる問題ではありません。Android の変更特性と、この構造が噛み合っていない ことが原因です。

UI 起点の変更が増えるほど、「どこにロジックを置くべきか」の判断が曖昧になり、結果としてレイヤー間の責務が崩れていきます。


MVVM + UseCase が量産されて価値を失う場合

MVVM + UseCase という構成は、多くの Android チームで採用されています。しかし、一定規模を超えたあたりから、次のような兆候が見え始めます。

  • 画面ごとに UseCase が増え続ける
  • 名前の違いしかない UseCase が並ぶ
  • テストされない UseCase が溜まっていく

これは、UseCase という概念が悪いわけではありません。

問題は、「UseCase を作ること」が目的化してしまうことです。本来は責務を明確にするための手段だったはずが、いつの間にか層を埋めるための存在になってしまいます。

この状態では、DDD を導入した意味はほとんど残りません。


本書が前提とする現実

本書では、次のような前提に立って話を進めます。

  • Android アプリは UI 変更が中心である
  • すべてのロジックをドメインに集約する必要はない
  • 設計は「きれいさ」よりも「壊しやすさ」が重要である

この前提を受け入れた上で、次章以降では「それでも DDD の考え方が役に立つ場面」を具体的に見ていきます。

DDD を捨てるためではなく、使える形に削ぎ落とすために