web-dev-qa-db-ja.com

mavenでのドメイン駆動設計のプロジェクト構造Java Spring-Boot

私のチームはジレンマに陥っており、次のようなタマネギのアーキテクチャを持つ既存のmaven Spring-Boot Java8プロジェクトがあります。

controller --> service --> dao --> jpa repositories
                            |  --> filesystem
                            |  --> jdbc template

Daoは以前、jdbcテンプレートとjpaを使用していたため、多くの方法でデータにアクセスする方法は複数ありました。しかし、古いJDBC Templateから新しいJPA Repositories、削除予定ですdao layerとリポジトリをサービスに直接注入します。

新しいアーキテクチャは次のようになります:-

controller --> service --> jpa repositories

私は今いくつかの懸念があります:-

  1. Daoの抽象化レイヤーを削除するこのアイデアはどの程度優れていますか?

  2. このアーキテクチャはドメイン駆動設計と関係がありますか?

  3. 私たちは約20のDaoクラスと50を超えるJpaRepositoriesとエンティティを持っているので、このリファクタリングに人時間を考慮したいのですが、それは巨大ですか、それともわずかですか?

  4. サービスクラスをGOD Classデータアクセスに関連するビジネスロジックと操作はどれですか。

2
Dave Ranjan

新しいアーキテクチャもドメイン駆動設計から派生したものではありません。もちろん、戦術パターンのコンテキストでは(戦略パターンのスコープはコードを超えるため)。

ドメインドリブンデザインには、システムの偶発的な複雑さを管理するのに役立つ多くの有用なビルディングブロックがあります。しかし、それらを適用する前に、非常に重要な質問に答える必要があります

システム/モジュールに本当にDDDビルディングブロックが必要ですか?

システムが単純なCRUDだけでなく、豊富なビジネスロジックを備えている場合は、答えは「はい」になります(もちろん、単純化されているため、多くの記事があります)。注:私はDDDの戦術的な部分について言及しています。 CRUDのようなアプリケーション(ユビキタス言語など)のDDD戦略的パターンイベントを使用することを本当に信じています。

トピックは非常に幅広いので、システムに組み込むことができるいくつかの簡単な手順を説明します(六角形アーキテクチャの概念ではありません)。

1)アプリケーションをモジュールに分割します。彼らはあなたより少ないでしょうBounded Contexts。 Javaでそれを行う方法? packagesを使用してください-それらは本当に強力です。

したがって、たとえばcom.mycompany.mysystem.order, com.mycompany.mysystem.invoice

2)あなたのBounded ContextはいくつかのAggregateに基づいて構築されます。集約は、1つのトランザクションで処理する必要があるすべてのものです。集約のルートは、JPAエンティティとして表すことができます。

@Entity
class Order {
@Id
String id;
List<Product> products;

void addProductToOrder(...) {
... some business logic
}

Money calculateDiscount(...) {
... some business logic
}

エンティティはリッチエンティティである必要があります-構造を保持するだけでなく、動作が含まれます。不変の値オブジェクトなどの概念を使用することもできます。

アグリゲートのリポジトリを作成しますが、ビジネスパーツのみです。アグリゲートを保存して取得できるようにします。たとえば、春のデータ。

4)いくつかのアクションを実行するために必要なメソッドを収集するFacadeを作成します。そこで検証を維持できますが、動作自体は集約内に維持する必要があることに注意してください。

5) Factory、Strategy、Observerなどの他のパタ​​ーンも使用できます。すべてのOOパターンはDDDにうまく適合します。

6)これらすべてのクラスをドメインパッケージに保持します。

com.mycompany.mysystem.order.domain
- Order.Java
- OrderRepository.Java
- OrderFacade.Java
- OrderFactory.Java

OrderFacadeのみを公開する必要があります。他のクラスにはパッケージスコープが必要です。

7)これで、別のサブパッケージ-インフラストラクチャを作成できます。そこではSpringの構成、Rest Controllerなどを維持します。ドメインに関連しないすべてのもの。

com.mycompany.mysystem.order.domain
    - Order.Java
    - OrderRepository.Java
    - OrderFacade.Java
    - OrderFactory.Java
com.mycompany.mysystem.order.infrastructure
    - OrderCommandController.Java
    - OrderConfiguration.Java

8) DDDでよく使用される非常に強力な概念が1つあります。これは[〜#〜] cqrs [〜#〜]と呼ばれます。あなたはそれについて読むことができます、多くの出典があります。上記の例に追加するためのヒントを1つ紹介します。

何百万通りもの方法でデータベースから何かを取得する必要がある状況はありますか?ええ、誰もがします。

したがって、CQRSに従って、コマンド/ビジネスオペレーションとクエリを分割できます。この例に従って、新しいサブパッケージを作成します

com.mycompany.mysystem.order.query

内部では、OrderQueryと呼ばれるエンティティを作成し、それをデータベース内の同じテーブルにポイントできます(またはより高度なケースではプロジェクションを使用します)。これで、新しいリポジトリ(Spring Data)を作成し、OrderQueryで使用できます。インフラストラクチャサブパッケージに、新しいコントローラーOrderQueryControllerを追加します。

これらの手順は明らかに単なるスケルトンであり、多くの簡略化が含まれています。開始して適切な方向に導くのに十分なはずです。

13