私は春ブーツと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
この手段は、それぞれの層は、独自のオブジェクトを操作し、決して他の層に渡します。
前もって感謝します。
私はあなたの質問は具体的には約であることを理解するものから、層内およびそのuseage logic
ティア。(したがって、presentation
およびdata
階層の問題の一部ではありません)。
関して PersonModel
私はあなたが何を意味するか、わからないPersonModel
とそれが実際に行いますが、一目で私はあなたが正常にちょうど頭上遅かれ早かれ、追加のコードの重複やメンテナンスを追加することになり、そのようなものを、必要はありませんと言うことができます。
関して PersonDto
DTO
S、名前が示すように、実際にクライアント(の間でデータを転送するためであることを意味している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]