web-dev-qa-db-ja.com

リポジトリパターン-それを理解する方法と「複雑な」エンティティでどのように機能するか

リポジトリパターンを理解するのに苦労しています。

リポジトリパターンは正しく行われました のようなトピックに関する多くの意見がありますが、 リポジトリは新しいシングルトンです または Do n't Use DAO use Repository または単に Spring JPA Data + Hibernate + MySQL + MAVEN ここで、RepositoryはDAOオブジェクトと同じように見えます。

私はこれが多くの記事に表示されているように難しいことではないので、私はこのものを読むのにうんざりしています。

私はそれを次のように見ます:私が欲しいのはこのようなものだと思われます:

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

Service Layer*DTOobjectsを取り、それらを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.save(ToolSetDTO toolSetDto)を使用してToolSetRepositoryを記述できます。このメソッドは、ToolSetDTOを「 store 」と認識します。しかし、ほとんどすべてのチュートリアルは*DTOではなく、Entityを渡します。

ここで私を悩ませているのは、上記のToolSetの例を使用する場合、次の手順を実行する必要があることです。

  1. toolSetDtoを取得し、nullでないか確認します
  2. toolSetDtoが所有するtool*Dtoごとに
    a)有効なIDを持っている場合は、DTOからEntityに変換します。そうでない場合は、新しいデータベースエントリを作成します
    b)toolDescriptionDtoをデータベースに変換/保存するか、新しいエントリを作成します
  3. 上記をチェックした後、ToolSet(エンティティ)をインスタンス化し、データベースに永続化するためにセットアップします

これはすべて複雑すぎて、単にサービス機能(クライアントのインターフェース)でこれを処理することはできません。

私が考えていたのは、例えばToolSetRepositoryが、ここでの質問は

  • ToolSetエンティティオブジェクトを使用しますか、それともDTOオブジェクトを使用しますか?
  • いずれにしても:*Repository use 他のリポジトリオブジェクトに許可されていますか? ToolSetを保存したいが、最初にToolToolDescriptionを保存する必要がある場合のように-ToolRepository内でToolDescriptionRepositoryToolSetRepositoryを使用しますか?
    その場合:なぜリポジトリパターンを壊さないのですか?このパターンが基本的にサービスと私のORMフレームワークの間のレイヤーである場合、依存関係の理由により、他の*Repositoryクラスに依存関係を追加することは「適切に感じられません」。

なぜこれを回避できないのかわかりません。 that 複雑に聞こえませんが、Spring Dataのような助けがまだあります。これが anything をどのように簡単にするか実際にはわからないので、私を悩ませているもう1つのことです。特に、すでにHibernateを使用しているので、メリットが見られません(ただし、別の質問かもしれません)。

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

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

62
displayname

あなたは私の「ダミーのリポジトリ」 post を読んで、リポジトリのシンプルなprincipleを理解することができます。あなたの問題は、DTOを使用していることであり、そのシナリオでは、リポジトリパターンを実際に使用せず、DAOを使用していることです。

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

ビジネスオブジェクトが単なるデータ構造である場合は、モデリングの問題、つまり設計の誤りがある可能性があります。リポジトリは、「リッチ」または少なくとも適切にカプセル化されたオブジェクトを使用するとより意味があります。データ構造をロード/保存するだけなら、おそらくリポジトリは必要ありません。ormで十分です。

他のオブジェクト(集約)から構成されるビジネスオブジェクトを処理し、そのオブジェクトがconsistent(集約ルート)になるためにすべての部分を必要とする場合、リポジトリパターンが最適なソリューションですすべての永続性の詳細を抽象化するためです。アプリは「製品」を要求するだけで、オブジェクトを復元するために必要なテーブルまたはクエリの数に関係なく、リポジトリは全体としてそれを返します。

コードサンプルに基づくと、「実際の」ビジネスオブジェクトはありません。 Hibernateで使用されるデータ構造があります。ビジネスオブジェクトは、ビジネスコンセプトとユースケースに基づいて設計されています。リポジトリにより、BLはオブジェクトがどのように永続化されるかを気にする必要がなくなります。ある意味では、リポジトリは、オブジェクトと永続化されるモデルとの間の「コンバーター/マッパー」として機能します。基本的に、リポジトリはオブジェクトを永続データに必要なものに「削減」します。

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

最大の間違いは、ストレージのニーズと考え方に従ってビジネスオブジェクトを設計することです。多くの開発者が信じていることとは反対に、ORMの目的はビジネスオブジェクトを永続化することではありません。その目的は、rdbms上で「oop」データベースをシミュレートすることです。 ORMマッピングは、dbオブジェクトとテーブルの間であり、アプリオブジェクト(ビジネスオブジェクトを処理する場合でも)とテーブルの間ではありません。

88
MikeSW