したがって、「Vaughn Vernonによるドメイン駆動設計の実装」を読んだ後、コアドメインの概念と思われるものを個別のモジュールに分離することにより、再利用性を高めるためにコードをリファクタリングすることにしました。
各モジュールには、ドメイン、インフラストラクチャ、アプリケーション/プレゼンテーションレイヤーを含む独自のアーキテクチャレイヤーのセットが含まれています(ヴォーンの推奨に従って、アプリケーションレイヤーの責任をルート、MVCコントローラー+テンプレートに存在するテンプレートからさらに分離することにしましたプレゼンテーション層)。
これらの各レイヤーを独自のパッケージ内に配置することにしました。各パッケージは、その下のレイヤーを依存関係として参照しています。つまり、プレゼンテーション層はアプリケーション層に依存し、アプリケーションはインフラストラクチャに依存します。リポジトリはドメインの一部であるため、各リポジトリインターフェースはドメイン層/パッケージ内に存在し、実装はインフラストラクチャ層/パッケージ(Doctrine 、など)。
この方法でコードを再構築することで、アプリケーションレイヤーをスワップアウトし、複数のWebアプリケーション間でドメインを再利用できることを願っています。
最終的にコードは再び形を整え始めているように見えますが、それでも私を混乱させるのは、アプリケーション、インフラストラクチャ、ドメインサービスのこの違いです。
ドメインサービスの一般的な例の1つは、パスワードのハッシュに使用するものです。ユーザーエンティティは、ユーザーの資格情報を格納するために使用される可能性のあるさまざまなハッシュアルゴリズムに関与する必要がないため、これはSRPの観点からは理にかなっています。
そのことを念頭に置いて、私はこの新しいドメインサービスを私のリポジトリと同じように扱いました。ドメインでインターフェースを定義し、実装をインフラストラクチャ層に任せることにより。しかし、私は今、アプリケーションサービスで何をすべきかについて考えています。
現在のところ、各エンティティには独自のアプリケーションサービスがあります。つまり、ユーザーエンティティにはアプリケーション層内にUserServiceがあります。この場合のUserServiceは、プリミティブデータ型の解析と一般的なユースケース「UserService :: CreateUser(string name、string email、etc):User」の処理を担当します。
私が気になるのは、アプリケーション層を交換することにした場合、複数のアプリケーションにわたってこのロジックを再実装する必要があるという事実です。だから私はこれが私の次のいくつかの質問につながると思います:
ドメインサービスは、インフラストラクチャレイヤーとモデル間の抽象化レイヤーを提供するために存在する単なるインターフェイスですか?例:リポジトリ+ HashingServicesなど
私はこのようなアプリケーションサービスを持っていると述べました:
Access / Application / Services / UserService :: CreateUser(string name、string email、etc):User
メソッドシグネチャは、プリミティブデータ型の引数を受け入れ、新しいユーザーエンティティ(DTOではない!)を返します。
これは、ドメインレイヤー内で定義されたいくつかのインターフェイスの実装としてインフラストラクチャレイヤーに属しますか、それともプリミティブデータ型の引数などにより、実際にはアプリケーションレイヤーがより適切ですか?
例:
Access/Domain/Services/UserServiceInterface
そして
Access/Infrastructure/Services/UserService implements UserServiceInterface
個別のモジュールが一方向の関係をどのように処理するか。モジュールAは、モジュールBのアプリケーションレイヤー(現在行っているように)またはインフラストラクチャの実装(個別のインターフェイスを介して)を参照する必要がありますか?
アプリケーション層サービスには別のインターフェースが必要ですか?答えが「はい」の場合、それらはどこに配置する必要がありますか?