dimanche 20 mars 2016

DDD: Creating reusable modules and service type distinctions (Domain, Infrastructure, Application)

So after reading "Implementing Domain-Driven Design by Vaughn Vernon" I've decided to refactor my code for better re usability by isolating what I believe to be core domain concepts into separate modules.

Each module contains their own set of distinct architectural layers which include the Domain, Infrastructure and the Application/Presentation layer (per Vaughn's recommendation I've decided to further separate the responsibilities of the Application layer from routes, MVC controllers + templates which exist in the Presentation Layer).

I've decided to place each of these layers within their own package; and each package is referencing the layer beneath it as a dependency. ie: Presentation Layer depends on the Application Layer, Application depends on Infrastructure, etc.

Since the Repository is a part of the Domain each Repository Interface exists within the Domain layer/package with implementation being a responsibility of the Infrastructure layer/package (Doctrine, etc).

I'm hoping that by restructuring my code in this way I'll be able to swap out the Application layer and reuse my Domain across multiple Web Applications.

The code finally looks like it's starting to shape again however what still confuses me is this distinction between Application, Infrastructure and Domain Services.

One common example of a Domain Service is something which you would use to hash passwords.

This makes sense to me from a SRP perspective since the User entity shouldn't concern itself with the many different hashing algorithms which might be used to store a user's credentials.

So with that in mind I treated this new Domain service the same way as my Repositories; by defining an interface in the Domain and leaving the implementation up to Infrastructure layer.

However, now I'm wondering about what should be done with the Application Services.

As it stands now, each Entity has its own Application Service.

ie: The User Entity has a UserService within the Application Layer.

The UserService in this case is responsible for parsing primitive data types and handling a common use-case "UserService::CreateUser(string name, string email, etc) : User"

What concerns me is the fact that I'll need to re-implement this logic across multiple applications should I decide to swap out the Application layer.

So I guess this leads me to my next few questions:

  1. Are Domain Services merely an Interface which exist to provide a layer of abstraction between the Infrastructure Layer and your Model? ie: Repositories + HashingServices, etc.

  2. When taking into consideration the example I provided above

Access/Application/Services/UserService::CreateUser(string name, string email, etc): User

-is responsible for parsing primitive integers, creating a User and returning an instance of the User Entity (not a dto!).

Does this in fact belong in the Infrastructure layer as an implementation of some interface defined within the Domain layer or is the Application Layer in fact more appropriate?

example: Access/Domain/Services/UserServiceInterface

and

Access/Infrastructure/Services/UserService implements UserServiceInterface

  1. How should separate modules handle unidirectional relationships. Should module A reference module B's application layer (as it's doing now) or infrastructure?

  2. Does the Application Layer require a Separate Interface?

Aucun commentaire:

Enregistrer un commentaire