Android アプリ開発は DDD できない

2022/09/13に公開

Android アプリ開発に DDD(ドメイン駆動設計) の要素を取り入れている方は多いと思います。
自分も DDD は素晴らしい考え方だと思ったので、より多くの要素を取り入れたいと考え、 DDD について調べました。
しかし、調べるほどに、 クライアントアプリ開発に DDD は適していない のではないかと思うようになりました。

前提として、「 Android アプリ」は、サーバーから API でデータを取得して表示するような「クライアントアプリ」を想定しています。

ドメインとは何か

ドメイン全体から考える

まずはクライアントアプリ開発という事情は置いておいて、 ドメイン全体 から考えてみます。
はじめにドメインモデルが抽出されます。リポジトリインターフェースが決まり、ユースケースが出来上がります。このあたりはサーバー側での実装になることが多いです。その後、 API や Web フロントエンド、その他クライアントアプリが作られます。

このように考えると、 クライアントアプリはドメイン全体の中のプレゼンテーション層 でしかありません。
クライアントアプリ開発を DDD で設計するというのは、 DDD のプレゼンテーション層を DDD で設計する と言っているのと同じではないでしょうか。

クライアントアプリ領域をドメインと見なせるか

DDD には サブドメイン という考え方があります。クライアントアプリ領域を一つのドメインと見なすことができれば、 DDD も可能でしょう。
しかし、クライアントアプリ領域は前述の通りプレゼンテーション層です。業務によって区切られたものではありません。プレゼンテーション層をドメインとして見ることは難しいと思います。
仮にカタログ的なドメインがあったとしても、そのドメイン層はサーバー側で実装されることになるでしょう。

そもそも クライアントアプリは、サーバーの「機能」と「情報」にアクセスするためのソフトウェア です。
まず、「アクセスすること」はユースケースであって、ドメインにはなりません。「機能」は完全にサーバー側にあるものでクライアントアプリの領域にはありません。「情報」に関してはコピーを得ることが可能ですが、本来持っていたルールやふるまいは削ぎ落とされています。
このことから、クライアントアプリには ドメインとして扱うものがない ことがわかるでしょう。

ふるまいを持てないクライアントのモデル

主な「機能」はサーバー側にあるので、クライアントアプリ側でモデルを作成しても、ルールやふるまいを持たせることができません。

仮に User というモデルがあり、名前の変更を行う場合、きちんとルールやふるまいを持っているならば、次のようなコードになります。

user.name = newName
repository.save(user)

user.name に新しい名前を設定する際、ルールに反しているなら例外を投げるなどの対応ができます。モデルがルールやふるまいを持ちます。

一方でクライアントアプリでは、 API の仕様によっては以下のようなコードを書かざるを得ません。

repository.updateName(user.id, newName)

モデルではなく、リポジトリ(API)がルールやふるまいを持つことになってしまっています。サーバー側に「機能」がある以上仕方のないことです。
クライアントアプリにも何らかのモデルは作られますが、このようにルールもふるまいも持てないようなモデルを「ドメインモデル」と呼ぶことはできないでしょう。

何をドメインと呼ぶのか

上記のように、クライアントアプリにはドメインと呼べるようなものがありません。
何をドメインと呼ぼうとしているのでしょうか。

例え話をします。
「日本の首都はどこですか?」
特に違和感なく、「東京です」と答えられます。
では、「神奈川県の首都はどこですか?」と聞かれたらどのように感じますか?
違和感があります。「首都」は「都道府県」に対して使うものではありません。

「プレゼンテーション層のドメインは?」と聞かれたら、同様に違和感があります。
「クライアントアプリのドメインは?」という質問も同じです。
クライアントアプリに対して、ドメインという言葉は使うものではないのではないかと思っています。

しかし、クライアントアプリ開発でもドメインという言葉は頻繁に目にします。これは「プログラムを適用する業務領域」とは別の意味で使われているように感じます。少なくともドメインをモデリングしたものはクライアントアプリにはないでしょう。
きちんとしたドメインモデルではないのなら、ドメインモデルとは別の名前を用いるべきだったのではないかと思います。 DDD の最初の仕事にも「ユビキタス言語を定義する」ことが含まれています。もちろんドメイン以外のものにも適切な名前を与えることは重要です。クライアントアプリに存在するモデルをドメインモデルと呼ぶことは、果たして本当に意思疎通を円滑にするものでしょうか。
私個人としては、クライアントアプリ開発の中で「ドメイン」「ドメインモデル」といった言葉があったことで大きく混乱しました。

まとめ

多くの人がクライアントアプリ開発に DDD を取り込もうとし、様々な解釈の DDD を発信しています。いくつか発信された記事を読んでみましたが、クライアント開発に DDD を取り入れることがゴールになってしまっているように感じました。

DDD は良いものだと思います。
しかし、クライアントアプリ開発に DDD を取り入れることで、必ず良いものになるとは限りません。DDD を取り入れた設計・開発をしたときのメリット・デメリットを考えなければならないでしょう。

また、クライアントアプリ開発に DDD を取り入れても、きちんとした DDD になることはないでしょう。 DDD とは呼ばずに、新たな設計手法として名前をつけるのが良いと思っています。

個人的には、 DDD にも用いられている考え方を取り入れるのは有用だと感じていますが、DDD をできるだけ多く、そのままの形で取り入れることは実装コストを増やすばかりだと感じています。
その点、 公式のアーキテクチャガイド はバランスが良さそうです。オプションとしてのドメイン層はあるものの、基本は UI 層とデータ層の 2 層です。これを基本とし、各プロジェクトに合わせて調整するくらいが良いように思いました。
他力本願ですが、 DDD と並ぶようなクライアントアプリ開発の定番の設計手法が生まれると良いな、と願っています。

Discussion