3層アーキテクチャにおけるサービスにおけるドメインモデルのために必要ですか?

氏は火星:

私は春ブーツとAPI休憩を構築していると私は、コミュニティが私を助けることができるかどうかを確認するために、私のアーキテクチャについての概念を明確にしたいと思います。

私のデータベースに私が呼ばれるテーブルを持っていることを想像してみてPerson私は、3層アーキテクチャに基づくアーキテクチャを取り付けています。次のように一般的なスキームは次のようになります。

  • 一方で私が持っているPersonDao.javaからタプル取得するために、データベースへのアクセスを担当される、Personテーブルを。これを行うには、それが呼ばれるクラスを使用していますPersonEntity.java(属性として)テーブルのすべての列が含まれています、。PersonDao.javaオブジェクトを返すために起こっているPersonModel.javaクラス。PersonModel.java表すクラスであるPersonビジネスモデルを。

  • 一方、私が持っているPersonService.java自分のアプリケーションのビジネスロジックを実行するための責任があるが、。このサービスは、呼び出し、PersonaDao.javaデータベースに格納された情報にアクセスします。PersonService.javaオブジェクトで動作しますPersonModel.java。このクラスは自分のアプリケーションのビジネスオブジェクトを表しているので、クラス。PersonService.java常に返されますPersonDto,java

  • 最後に、PersonController.javaこのコントローラは、REST APIに接続インターフェースを公開いずれかになります。彼はいつもDTOとと通信と連携PersonService.javaだけでなくDTO経由。

PersonController <-> (PersonDto) <-> PersonService <-> (PersonModel) <-> PersonDao <-> (PersonEntity) <-> DB

質問です:それは使う必要があるPersonModel.javaように、クラスPersonService.javaにのみ、このクラスのオブジェクトで動作しますか?またはそれが良いだろうPersonService.javaクラスのオブジェクトを直接操作するためにPersonEntity.java私はこのようにそれを行う場合には、それぞれの層にのみその範囲のオブジェクトで動作するように、単一責任の原則を維持することです。

答えがある場合、それはPersonModel.javaそれぞれの層の単一責任の原則を維持することが必要です。何か変更があればJpaRepository使用されましたか?私はこの質問をした場合、多くのチュートリアルと例では、私はときに見るのでそれはJpaRepository使用され、サービスが実体を直接操作します。このケースでは、我々はサービスのためのビジネスオブジェクトを表すクラスを作成するべきではないのですか?

EDIT:この質問への答え(に?春のエンティティがサービスにDTOに変換する必要があります)、私の頭の中で理にかなっているアーキテクチャが反映されますが、確かにそれは最も正しいものではありません。私が来るの結論は、それぞれの層は、オブジェクトの独自の種類を使用するだろうということです。コピー/答えを貼り付けます。

通常は、異なる層を持っています:

  • データを格納する永続化層
  • ビジネスデータを操作するための層
  • プレゼンテーション層は、データを公開します

一般的に、それぞれの層は、オブジェクトの独自の種類を使用します。

  • 永続層:リポジトリ、エンティティ
  • ビジネスレイヤ:サービス、ドメインオブジェクト
  • プレゼンテーション層:コントローラ、のDTO

この手段は、それぞれの層は、独自のオブジェクトを操作し、決して他の層に渡します。

前もって感謝します。

ケナンGüler:

私はあなたの質問は具体的には約であることを理解するものから、内およびそのuseage logicティア。(したがって、presentationおよびdata階層の問題の一部ではありません)。

関して PersonModel

私はあなたが何を意味するか、わからないPersonModelとそれが実際に行いますが、一目で私はあなたが正常にちょうど頭上遅かれ早かれ、追加のコードの重複やメンテナンスを追加することになり、そのようなものを、必要はありませんと言うことができます。

関して PersonDto

DTOS、名前が示すように、実際にクライアント(の間でデータを転送するためであることを意味しているpresentation層)とあなたのAPI(controller / boundary内層logic tierあなたの「クライアントにやさしい」プレゼンテーション公開するために使用されている)ドメインモデルをオーバーを調整するために、下-フェッチと-何とか(おかげGraphQLこれは現在ではほとんどもはや問題ではありません)。あなたのビジネスのサービスクラスを知っているか、または全くのDTOに対処する必要はありません。

すでに述べたようにまた、のためにSRPどのような方法で、ビジネスやDAOクラスは、追加のデータマッピング(エンティティ< - - >モデル、モデル<>例えばDTO)を扱うべきではありません。彼らはすでに(参照ロジック層内の特定のタスク果たす境界層サービス層を)。

関して PersonEntity

これは、通常の両方を表すものです本当のあなたからエンティティを問題ドメインdata(NoSQLの中に例えばデータベーステーブルRDBMS内または文書)ティア。だから、それはかなり一般的です

  • エンティティクラスは、次のような接尾辞なしで命名されていることEntityちょうどそれのためにプレーンな名前を使用して、例えばPerson

  • エンティティクラスがためにそれらが表示されるように、追加の注釈(例えばJPA)を含有することORM layer、(たとえば、休止状態)

  • エンティティクラスは必ずしもすべきではないことを貧血と実際に(あなたがあなたとやってみたかった、おそらく何をいくつかaddditional行動が含まれているPersonModelクラス)、たとえば、

class Person {
  Date birthday;

  int getAge() { /* calculate age based on the birthday */ }

  boolean isAdult() { /* getAge() >= 18 */ }
}

アップラッピング

ユースケース:の作成Personエンティティ

Hinflug(アウトバウンド便)

[Client] --> (data: JSON) --> <Deserialization as `PersonDTO`> --> <DTO Validation> --> [PersonController] --> <AutoMapping to `Person` entity> --> [PersonService] --> [PersonDao] --> <ORM and JDBC> --> <Entity Validation> --> DB

注:<Validation>また、手動でコントローラ内で行うことができますが、通常ビーン検証APIは、このプロセスを自動化するために使用されるその背景に良いことは、あなたがあなたのDTOとエンティティ(例えばとの両方を検証するためにビーン検証APIを使用することができているHibernateバリを)。

帰りの飛行機(帰りの飛行機)

DB --> <ORM and JDBC> --> [PersonDao] --> [PersonService] --> <AutoMapping to `Person` entity> --> [PersonController] --> <AutoMapping `Person` entity to `PersonDTO`>  --> <Serialization of `PersonDTO`> --> (data: JSON) -> [Client]  

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=378783&siteId=1