webdevilopers / php-ddd

PHP Symfony Doctrine Domain-driven Design
202 stars 10 forks source link

Directory Structure, Namespaces and Naming Conventions #32

Open webdevilopers opened 7 years ago

webdevilopers commented 7 years ago

I initially startet a post here focussing on where to put @Symfony bundles:

Recently I found an example for @silexphp by @danitome24:

He was also inspired by the @dddinphp book. Allthough he does not use the Domain\Model directory. Instead he is separating Entity from ValueObject. I prefer the approach to share the same folder for Domain Models that belong to an Aggregate.

Instead of Domain\Entity\User and Domain\ValueObject\UserId it should be Domain\Model\User\User, Domain\Model\User\UserId etc..

I'm not sure about the Application layer though. Though it is not the Domain Layer I prefer the same approach in order to quickly identify which Commands, Handlers etc. relate to an aggregate:

What are your thoughts on this @danitome24?

Silex commented 7 years ago

This is not the @Silex you are looking for :wink:

webdevilopers commented 7 years ago

"Fixed" @Silex ! ;)

danitome24 commented 7 years ago

Hi @webdevilopers,

The only reason of my folders separation is a point of view. I've started working with DDD on a big project one and I see that if I put all in a "context" folder like domain or services it will be a big bag. I divided into separated folders to keep it simple. That's the main reason!!

What do you think about that? I'm interested to learn other points of view!!

Thanks for read my little project.

webdevilopers commented 7 years ago

I think if an aggregate grows it is fine to add some subdirectories e.g. for Events and Exceptions like this @prooph example:

But in any way I find it most important to separate code - at least inside the Domain layer - regarding Domain and not architectural terms as @theUniC stated here:

But even in the Application layer the @dddinphp book suggests the same approach:

I have an app with 20 Commands and Handlers and maybe it's ok to add a Command and CommandHandler folder. But for know I stay with this structure.

A lot of files actually make rethink my aggregates - maybe I should create more smaller aggregates or move stuff to other bounded contexts.

Feel free to join the discussion here too:

danitome24 commented 7 years ago

Agree with you, I think that architectural and domain terms should be balanced and is useful to separate code into folders... Otherwise, the Domain will be the same... Only where to find some components will change his path but not his context.

webdevilopers commented 7 years ago

Recently I watched "Event Sourcing: the good, the bad and the complicated" by @Ocramius:

At some point he states that "Command"s belong in to the Domain Layer. I was suprised! Not only because of my previous comments and examples here about @dddinphp:

But also because of a post of him where I interpreted that I should put them into the Application Layer:

Since the command handler is part of our application layer, we are effectively diluting these checks into "less important layers".

Looking at the current @prooph examples Commands and Handlers are both placed inside the Domain Layer. Allthough I think you can say that this Domain Layer is not "domain driven designed":

@codeliner explained to me:

commands are definitely part of the domain, handlers are a bit tricky. On the one hand they are glue code on the other hand they use the UL and only interact with interfaces defined by the domain. We've but them next to the commands because it is easier to understand if commands and handlers are not spread across the application. If you tend to see handlers as glue components then put them in the application layer.

What if you took all the Commands and Handlers and put them back CRUD style in a single Service? Personally I don't think the Domain Model should know or better "care" about a Command and maybe its superficial validation. The data can come from everywhere - Application Layer, Console whatever. It just has to know what data it is and ensure that it has been "transformed" into the Domain language e.g. Value Objects.

Maybe there is a major difference between using DDD and DDD w/ CQRS and Event Sourcing? Since the Commands are also used to test the Events inside an Aggregate Root.

What do you guys think @mathiasverraes @carlosbuenosvinos @tjaskula?

Related:

mathiasverraes commented 7 years ago

The whole "domain layer vs application layer" is a bit of a false dichotomy anyway. Commands are domain concepts, if they actually use domain language and represent things the business needs, as opposed to vague wording like "create customer". (If you could create customers you'd be rich fast) A command handler is function that know how to apply a command (domain) to the model (domain), so it makes sense that it would be part of that domain, except I'd never discuss command handlers with business people. The command handler can be pure domain terminology inside, but they're also a good place to put transaction logic. This is leaky, until you realise that understanding consistency and failures and rollbacks are important for a business, not just a dev, so now transactions become domain concepts. Etcetera. The point is that it doesn't really matter in what layer something is. What I value is good, understandable domain models, where code that conceptually belongs together, lives together — eg a command that affects a change in some domain object is located close to that object. It helps me to find stuff and see at first glance what I need to know about some feature. And favour putting things together based on business processes as opposed to arbitrary structure. eg /EmployeeOnboarding/HireEmployee /EmployeeCompensation/EmployeeSalary as opposed to organising based on a big central Employee object.

tjaskula commented 7 years ago

Hi,

I think I gave all the arguments in the linked stackoverflow response (i.e. http://stackoverflow.com/a/32232230/261950 http://stackoverflow.com/a/32232230/261950). As I said, it’s a tradeoff how you organize you application from the architectural point of view. You have to be aware of the pro and cons of your solution. As the domain is central, commands and events (business intention and fact) are generally a best fit there. Where you place command handlers, event publishers etc, depends really on functional and non functional requirements. Also I don’t see a difference on where the commands/events should be if you do plain DDD or CQRS/Event Sourced systems. There is many ways to do, and there is no a single rule to follow.

Regards,

Thomas

Le 9 avr. 2017 à 20:18, webDEVILopers notifications@github.com a écrit :

Recently I watched "Event Sourcing: the good, the bad and the complicated" by @Ocramius https://github.com/Ocramius:

https://www.youtube.com/watch?v=8NuHNtwjync https://www.youtube.com/watch?v=8NuHNtwjync At some point he states that "Command"s belong in to the Domain Layer. I was suprised! Not only because of my previous comments and examples here about @dddinphp https://github.com/dddinphp:

https://github.com/dddinphp/last-wishes/tree/master/src/Lw/Application/Service https://github.com/dddinphp/last-wishes/tree/master/src/Lw/Application/Service But also because of a post of him where I interpreted that I should put them into the Application Layer:

Since the command handler is part of our application layer, we are effectively diluting these checks into "less important layers".

https://ocramius.github.io/blog/on-aggregates-and-external-context-interactions/ https://ocramius.github.io/blog/on-aggregates-and-external-context-interactions/ Looking at the current @prooph https://github.com/prooph examples Commands and Handlers are both placed inside the Domain Layer. Allthough I think you can say that this Domain Layer is not "domain driven designed":

https://github.com/prooph/proophessor-do-symfony/tree/master/src/ProophessorDo/Model/User https://github.com/prooph/proophessor-do-symfony/tree/master/src/ProophessorDo/Model/User @codeliner https://github.com/codeliner explained to me:

commands are definitely part of the domain, handlers are a bit tricky. On the one hand they are glue code on the other hand they use the UL and only interact with interfaces defined by the domain. We've but them next to the commands because it is easier to understand if commands and handlers are not spread across the application. If you tend to see handlers as glue components then put them in the application layer.

What if you took all the Commands and Handlers and put them back CRUD style in a single Service? Personally I don't think the Domain Model should know or better "care" about a Command and maybe its superficial validation. The data can come from everywhere - Application Layer, Console whatever. It just has to know what data it is and ensure that it has been "transformed" into the Domain language e.g. Value Objects.

Maybe there is a major difference between using DDD and DDD w/ CQRS and Event Sourcing? Since the Commands are also used to test the Events inside an Aggregate Root.

What do you guys think @mathiasverraes https://github.com/mathiasverraes @carlosbuenosvinos https://github.com/carlosbuenosvinos @tjaskula https://github.com/tjaskula?

Related:

http://stackoverflow.com/questions/32216408/cqrs-commands-and-queries-do-they-belong-in-the-domain http://stackoverflow.com/questions/32216408/cqrs-commands-and-queries-do-they-belong-in-the-domain — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/webdevilopers/php-ddd/issues/32#issuecomment-292800130, or mute the thread https://github.com/notifications/unsubscribe-auth/AAKzM_zxb4pzUElsTWyfqtr6zqn3dvt4ks5ruSEPgaJpZM4Mk3sG.

webdevilopers commented 5 years ago

Recently @vkhorikov posted a new interesting post about "Commands in Domain Layer":

Just my two cents: Currently our Commands share the Service namespace in our Application Layer. Though they are not pure DTOs that only use primitives. Instead they have a named constructor receiving an object e.g. "Request" and then directly converting them into value objects. This removes possible converting from the Application Handler.

The reason for this is that our UI Tasks are reflected directly by the commands. That makes it easier to talt to our UI developers by "keeping them away" from our Domain Layer. ;)

Our handler than "converts" the UI Task into our "Domain intention": PlaceOrder(Command) -> PlaceOrderHandler -> Order::place($command->orderId())

But I also agree with @tjaskula : It can depend on the pattern used. I always put Domain Events into the Domain Layer. And some patterns - I think the Actor pattern - does not use Handlers and directly passes Commands to Domain Models. Then I would place the Commands in my Domain Layer too.

Some thoughts on this here by @matthiasnoback:

Thanks in advance for sharing your thoughts.

Came from: