1. ホーム
  2. java

[解決済み] Repository Pattern - どう理解し、"複雑な "エンティティでどう動くのか?

2023-07-09 16:38:27

質問

Repositoryパターンを理解するのに苦労しています。

のように、そのトピックについて多くの意見があります。 正しく行われたリポジトリパターン のようなものもありますが、他にも リポジトリは新しいシングルトン のように、あるいはまた DAOを使わず、リポジトリを使う または、単に Spring JPAデータ + Hibernate + MySQL + MAVEN で、なぜかリポジトリがDAOオブジェクトと同じに見える。

多くの記事で表示されているように、イマイチこれがそんなに難しいことであるはずがないので、私はこのようなものを読むのに疲れてきています。

私はそれをこのように見ています。私が欲しいのはこのようなものであるように見えます。

         ------------------------------------------------------------------------
         |                            Server                                    |
         ------------------------------------------------------------------------
         |                    |                        |                        |
Client <-|-> Service Layer  <-|->  Repository Layer  <-|-> ORM / Database Layer |
         |                    |                        |                        |  
         ------------------------------------------------------------------------

Service Layer*DTO オブジェクトを受け取り、それを Repository Layer に渡すだけであり、基本的には どのように を知っている人」以外の何者でもありません。

例えば、いくつかのツールのコンポジションがあるとします ( これは単なる擬似的なコードであることに注意してください )

@Entity
class ToolSet {
  @Id
  public Long id;
  @OneToOne
  public Tool tool1;
  @OneToOne
  public Tool tool2;
}

@Entity
class Tool {
  @Id
  public Long id;
  @OneToMany
  public ToolDescription toolDescription;
}

@Entity
class ToolDescription {
  @Id
  public Long id;
  @NotNull
  @OneToOne
  public Language language

  public String name;
  public String details;
}

を取得していないのは、その部分です。 ToolSetDTO オブジェクトを取得している部分です。

私がこれまで理解していたように、私は ToolSetRepository というメソッドで ToolSetRepository.save(ToolSetDTO toolSetDto) その " を格納する方法を知っています。 "である。 ToolSetDTO . しかし、ほとんどすべてのチュートリアルは *DTO を渡さずに Entity の代わりに

ここで気になるのは、もしあなたが私の ToolSet の例をとると、次のようなステップを踏まなければならないことです。

  1. を取る toolSetDto でないかを確認し null
  2. それぞれについて tool*Dto が所有する toolSetDto

    a) 有効な ID がある場合、以下のように変換します。 DTO から Entity そうでない場合は、新しいデータベースエントリを作成します。

    b) toolDescriptionDto で、それをデータベースに変換/保存するか、新しいエントリを作成します。
  3. 上記を確認後、インスタンス化 ToolSet (エンティティ)をインスタンス化し、データベースに永続化するように設定します。

これらすべては、サービス機能(クライアントのためのインターフェース)に単にこれを処理させるには、あまりにも複雑です。

私が考えていたのは、たとえば ToolSetRepository を作成することですが、ここでの疑問は

  • を取るのでしょうか? ToolSet エンティティオブジェクトを取るのか、それとも DTO オブジェクトを使うのでしょうか?
  • いずれにせよ は *Repository は許可されていますか? 使用 他のリポジトリオブジェクトを使用できますか?例えば、私が保存したい ToolSet を保存したいが ToolToolDescription を使うか、それとも ToolRepositoryToolDescriptionRepository 内側 ToolSetRepository ?

    もしそうなら なぜそれはリポジトリパターンを壊さないのでしょうか?もしこのパターンが基本的にサービスと私のORMフレームワークの間のレイヤーであるなら、他の *Repository クラスへの依存を追加することは正しいこととは思えません。

なぜこれが理解できないのかわかりません。それは、音 その のようなヘルプがあります。 Spring Data . もう一つ気になるのは、これがどのようにして 何もかも をより簡単にするのかがわからないからです。特に私はすでにHibernateを使用しているので、その利点がわかりません(しかし、それは別の質問かもしれません)。

だから......私はこれが長い質問であることを知っていますが、私はすでにそれに研究の数日間を費やしました。私が今作業している既存のコードがすでにあり、このパターンを見通すことができないので、混乱し始めます。

私は、誰かが私にリポジトリパターンの非常に非常に単純な例を実装することを越えて取得しない記事やチュートリアルのほとんどよりも大きな画像を与えることができることを願っています。

どのように解決するのですか?

リポジトリ for dummies" を読んでください。 ポスト を読んで、簡単な 原則 を理解する必要があります。あなたの問題は、DTOで作業していることだと思います。そのシナリオでは、実際にはリポジトリパターンを使用せず、DAOを使用しているのです。

リポジトリとDAOの主な違いは、リポジトリはオブジェクトのみを返すということです。 呼び出し側のレイヤで理解される . ほとんどの場合、リポジトリはビジネス層で使用されるため、ビジネスオブジェクトを返します。ダオはデータを返しますが、それはビジネスオブジェクト全体であるかどうか、つまりデータが有効なビジネスコンセプトであるかどうかはわかりません。

ビジネスオブジェクトが単なるデータ構造である場合、それはモデリングに問題がある、つまり設計が悪いということを示唆しているかもしれません。リポジトリは、「リッチ」なオブジェクト、または少なくとも適切にカプセル化されたオブジェクトでより意味をなします。データ構造をロード/セーブするだけなら、リポジトリは必要ないでしょうし、ORMで十分です。

もしあなたが他のオブジェクトから構成されたビジネスオブジェクト(集合体)を扱っていて、そのオブジェクトがすべてのパーツを 一貫性 (集合体ルート)を扱う場合、リポジトリパターンはすべての永続性の詳細を抽象化するため、最良のソリューションです。アプリはただ '製品' を要求し、リポジトリはオブジェクトを復元するためにいくつのテーブルやクエリーが必要であろうと、全体としてそれを返します。

あなたのコードサンプルに基づくと、あなたは「本当の」ビジネスオブジェクトを持っていません。Hibernate が使用するデータ構造を持っています。ビジネスオブジェクトは、ビジネスの概念と使用事例に基づいて設計されています。リポジトリは、BLがそのオブジェクトがどのように永続化されるかを気にしないようにすることを可能にします。ある意味、リポジトリはオブジェクトと永続化されるモデルの間の「コンバーター/マッパー」として機能します。基本的に、リポジトリはオブジェクトを永続化のために必要なデータに「還元」します。

ビジネスオブジェクト ORMエンティティではありません。 技術的な観点からはそうかもしれませんが、設計の観点からは、一方はビジネスのものをモデル化し、もう一方は永続性のものをモデル化しています。多くの場合、これらは直接的には互換性がありません。

最大の間違いは、ストレージのニーズと考え方に従ってビジネスオブジェクトを設計することです。多くの開発者が信じていることに反して、ORM の目的はビジネス オブジェクトを永続化することではありません。その目的は、RDBMS の上に 'OOP' データベースをシミュレートすることです。ORMのマッピングは、データベースオブジェクトとテーブルの間であり、アプリケーションオブジェクト(ビジネスオブジェクトを扱う場合はなおさらです)とテーブルの間ではないのです。