

はじめまして。

DDDやクリーンアーキテクチャについてある程度勉強をして、それぞれのオブジェクトがどういう役割を担うのかは何となく理解したというレベルにいます。

ただ、実際のサービスをDDD＋クリーンアーキテクチャで設計をしようとしてもドメインモデルが何になるのかをいまいちつかめません。

Instagramっぽいサイトを例にして考えています。

”ユーザーのプロフィールを見る”というユースケースを実装します。  
プロフィールで見れる情報として今回は、アイコン、投稿数、フォロワー数、フォロー数、名前、説明文、リンク、投稿した写真一覧を利用します。  
閲覧できるプロフィールは自分のプロフィールと相手のプロフィールの２パターンがあって、自分のプロフィールの場合は登録年月日を、相手のプロフィールの場合はそのユーザーをフォローしてるかどうかを表示します。

まず、この場合はユーザーの関心はプロフィールにあるのでプロフィールが一つのドメインモデルになると考えました。  
プロフィールはユーザーの登録情報だけで成り立っているものではなく、投稿した写真にも関係があります。  
なのでプロフィールはユーザーエンティティをルートとした集約だと考えます。

ただ、これ以上どうやってモデルに落としこむのか考えてもさっぱりわかりません。  
ユーザーや写真はエンティティになりそうだな、とかぐらいは考えつくのですが・・・  
プロフィールというドメインモデルはどんな属性を持ちどんな振る舞いをするのか、ユースケースは何をするのかなど全然分かりません。

おそらく実際の設計パターンを何回も見ていくうちに感覚を掴めるようになるかと思うのですが・・・

この場合はどんな設計にするべきなのか教えて下さい。


CC BY-SA 3.0
2016-08-04T14:38:48.697
28068
2016-09-27T23:49:49.720
18386
question
ドメイン駆動設計
DDD(ドメイン駆動設計)でドメインモデルの切り出し方について質問です。


「データを見る」というユースケースからは、ドメインの振る舞いがあまり出てこないので、恐らくこれを題材にすると、質問者さんのように行き詰まってしまうと思います。  
「DDD CQRS」といったキーワードでぐぐってみると分かりますが、ドメインモデルが威力を発揮するのは更新系の処理です。

> プロフィールはユーザーの登録情報だけで成り立っているものではなく、投稿した写真にも関係があります。  
>  なのでプロフィールはユーザーエンティティをルートとした集約だと考えます。

プロフィール画像ならまだしも、写真共有サイトにおける投稿写真は、プロフィールとは異なる集約にすべきです。  
集約とは整合性を保たなければならない境界、トランザクション境界です。  
プロフィールと投稿写真のトランザクション境界は、異なるものだと思います。  
例えばこんな感じ：

[プロフィール]エンティティ (集約ルート)  
＋ユーザID  
＋名前  
＋自己紹介文  
＋...

※ユーザという概念とプロフィールという概念を別のモデルにすべきかどうかは、今の情報だけでは判断つかない・・・

[投稿写真]エンティティ (集約ルート)  
＋投稿写真ID  
＋投稿者のユーザID  
＋名前  
＋...

※投稿写真の画像データそのものは別のストレージに保存し、ドメインではIDだけ持つのが良いと思います

> プロフィールで見れる情報として今回は、アイコン、投稿数、フォロワー数、フォロー数、名前、説明文、リンク、投稿した写真一覧を利用します。

先にもCQRSという言葉をあげましたが、「プロフィール画面で見れる情報」と「プロフィールエンティティが持つべき属性」は、必ずしも一致しません。  
投稿数やフォロワー数などは、ドメインモデルとは分離したクエリを用意する方が良いと思います。  
そうすると、クエリ用のテーブルを別途用意し、定期バッチなどで集計された情報を返すようにするなど、パフォーマンスのために色々と手を加えても、ドメインモデルに影響を与えずに済みます。


CC BY-SA 3.0
2016-08-05T12:48:14.477
28086
2016-08-05T12:48:14.477
8078
28068
answer


@mok2pok さんが、とてもいい回答を記述してくださっていますが、  
一見しただけだと理解できなかったので、自分が調べた補足情報を。

CQRS とは Command and Query Responsibility Segregation
パターンであり、アーキテクチャ的なデザインパターンのひとつ。  
参照: <https://msdn.microsoft.com/en-us/library/dn568103.aspx>

コマンド(更新系の処理)とクエリ(参照系の処理)のモデルを分離するすることによって、モデルが読み込み・書き込みの両方を考慮しなければならない場合に発生する複雑さを回避しよう、という試みです。

DDD と併用される場合には、 @mok2pok さんのおっしゃるとおり、読み込みのロジックをなくすような、薄い Dto を用意する様子です。


CC BY-SA 3.0
2016-09-27T23:49:49.720
29193
2016-09-27T23:49:49.720
754
28068
answer