質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

Q&A

1回答

225閲覧

ドメイン駆動設計におけるリポジトリの設計について

Nekodesu

総合スコア0

アーキテクチャ

アーキテクチャとは、情報システム(ハードウェア、OS、アプリケーション、ネットワーク等)の設計方法、設計思想、設計思想に基づいて構築されたシステム構造をアーキテクチャと呼びます

0グッド

0クリップ

投稿2024/08/09 04:41

ドメイン設計で開発を行っています。
リポジトリについての理解が難しく混乱しているので質問させてください。

例えばなのですが、オーナーとユーザーという概念が存在しているとします。
オーナー1人につきユーザーが複数存在してオーナーはユーザーの管理者です。
オーナーだけがタグを作成できる機能があり、ユーザーはオーナーが作成したタグを選択(複数可)することができます。

この場合、テーブルとしては「タグテーブル」と「ユーザー選択タグテーブル」が必要だと思います。
テーブルの構成としてはこのようなものと仮定します。

タグテーブル
tag_id | owner_id | tag_name

ユーザー選択タグテーブル
tag_id | user_id

この場合、タグを保存する際はTagRepositoryを用意して保存すればいいと考えています。
しかし、ユーザーがタグを選択して保存する際にリポジトリをどのように定義すればいいのかがわかりません。
タグ選択はタグIDのみが配列で渡されるという動作を考えていて、このタグIDのみを保持するドメインオブジェクトを作成する必要があるのでしょうか?
また、ユーザーが選択画面でタグ情報を取得する際はタグID+タグ名が必要になりこちらも別途ドメインオブジェクトが必要でしょうか?(保存時のドメインオブジェクトと共通でいい?)

・オーナーがタグを保存する際は、タグ用のドメインオブジェクトを用意して、TagRepositoryで永続化する
・オーナーがタグを取得する際は、TagRepositoryからデータを取得して、タグ用のドメインオブジェクトに変換する
・ユーザーが選択タグを保存する際は、選択タグ用のドメインオブジェクト(param: tag_id, name = null)を作成して、選択タグ用のドメインオブジェクトの配列の中からtag_idを抜き出してSelectTagRepositoryで永続化
・ユーザーが選択タグを取得する際は、SelectTagRepositoryからデータを取得して、選択タグ用のドメインオブジェクトに変換する。
まとめると自分の認識ではこのように考えています。
しかし、選択したタグIDを保存するのにリポジトリは必要なのかという疑問と、保存時はnameが常にnullになることに疑問を感じています。

リポジトリについて理解が浅く頓珍漢なことを言っていると思いますが、よろしければ回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

理想の話をすると、ユーザーに関する保存処理はUserRepositoryの保存メソッド(Saveなど)だけを通して行うみたいな感じかと思います。現実的にはなかなかそうも行かない気もしますが。

回答にあたって以下のような前提とします。

  • モバイルアプリとします
  • 言語はC#で例示します(自分が慣れてるので)
  • データの保存はサーバーサイドのWebAPIを経由するものとします。

まずはユーザーを保存するためのUserRepositoryを用意します。

cs

1public class Tag 2{ 3 public int Id {get; private set;} 4 public string Name { get; private set; } 5 6 public Tag(int id, string name) 7 { 8 Id = id; 9 Name = name; 10 } 11} 12 13 14public class User 15{ 16 public int Id { get; private set; } 17 // 選択中のタグ 18 public List<Tag> Tags {get; private set; } 19 20 public User(int id, List<Tag> tags) 21 { 22 Id = id; 23 Tags = tags; 24 } 25 26 public void SetTags(List<Tag> tags) 27 { 28 Tags = tags; 29 } 30} 31 32public class UserRepository 33{ 34 public async Task<User> Get(int id) 35 { 36 // idを指定してユーザー情報(JSONとか?)を取得してUserのインスタンスを作る処理 37 var user = ....; 38 39 return user; 40 } 41 42 public async Task Save(User user) 43 { 44 // WebAPIへのリクエスト 45 } 46 47} 48

ユーザーのタグ編集画面では、TagRepositoryでタグ一覧を取得して画面に表示して、なおかつUserの選択中のタグ(List<Tag>)を下に選択中かどうかわかるようにUIに反映してやればいいかなと。
保存ボタンなどが押された場合に、User#SetTags()で画面で選択されたタグの一覧を渡してやって、UserRepository#Saveで保存するみたいな感じかと思います。

投稿2024/08/11 23:39

編集2024/08/11 23:47
mingos

総合スコア4190

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nekodesu

2024/08/13 01:04

ご回答ありがとうございます。 選択タグをユーザーの集約にするという考えがありませんでした。 追加で質問させていただきたいです。 この機能の開発で必要なドメインオブジェクトとリポジトリはこのような感じでしょうか? オーナーによるタグ登録 ・オーナー(ドメインオブジェクト) param: int id, Tag tag ・タグ(ドメインオブジェクト) param: string name ・オーナーリポジトリ ユーザーによるタグ選択 ・ユーザー(ドメインオブジェクト) param: int id, SelectTag tag ・選択タグ(ドメインオブジェクト) param: int id, string name ・ユーザーリポジトリ ユーザーがタグを選択する際はnameを保存する必要がないので、こちらにはnullが常に入るようにしてオブジェクトを生成すればいいでしょうか?選択タグをデータベースから取得する際はリポジトリで選択タグのIDとタグテーブルをJOINして名前を取得して選択タグオブジェクトに詰め込むのが適切ですか?
mingos

2024/08/13 02:48

ドメイン駆動設計で進めるのであれば、ドメインオブジェクトにはデータベースの実装を意識させないようにするべきではないでしょうか? 「ユーザーがタグを選択する際はnameを保存する必要がない」ということは考えてはいけません。 ユーザーリポジトリの保存、取得処理ではもちろんそれは必要ですが、Userオブジェクトはそれを考えるべきではないので、UserにTagを集約するわけです。 UserRespoitoryのSaveメソッドではユーザーのオブジェクトを渡すだけ。 内部で必要なテーブルにINSERT,UPDATEをするが、それは利用側は意識しない。 UserRepositoryのGetメソッドでは、ユーザー、選択中テーブル、タグテーブルからSELECT、必要なJOINして必要な情報を全て取得して、Userのインスタンスを生成して返す。 100%正解というわけではないかもしれませんが、以上が自分の考え方です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問