I'm going to keep this short as I wanted to answer, but am strapped for time and don't have a clear picture about what exactly you're looking for. One of the MOST important thing about domain-driven design questions and answers is that you MUST always ask questions within a context. As with a lot of things, "it depends" comes up a lot.. even more-so in DDD.
First, a subdomain represents a delimited (partitioned) piece of the overall domain. A domain could be something like "Scholarships Management". There will be several subdomains inside of that. You might consider something like:
- Identity and Access Management (generic subdomain)
- Student Application (core)
- Selection Process (core)
- Financing (core)
- Logging and Audit (supporting subdomain)
Subdomains represent partitions of the "problem space". They represent different logical areas of responsibility in an application and they are completely dependent on the domain. Don't go on a witch-hunt expecting to find a bunch of these either. I've seen plenty of people try to split a simple application into 5-6 subdomains. It doesn't make sense. You have to make sense of the situation you're in and really get good at "reading the lay of the land". It takes practice.
Bounded context represents the ubiquitous language of (in a perfect world) a single sub-domain. This is where things get sketchy, but for sake of example... while subdomain is definition of focused problem space, bounded context is the application of a domain model that is formed by the UL as a solution to a particular subdomain. This is a little bit of a general statement, but Bounded Context (as an applied domain model) can be thought of as "the solution" to the problem presented by a sub-domain.
As I mentioned, a bounded context mapping one-to-one with a subdomain isn't always the case, but what's important is that the identification of a bounded context occurs because you discover that the language your business uses changes based on context. For example, when a student starts to complete an application for a scholarship, they think of themselves as a "student". However, when they meet the requirements for some scholarship, they become a "candidate" in the context of selection. The difference is subtle, but important. In addition, personnel in the "finances" context may not even care that a student exists as a concept at all.
So... this got long... back to your question...
And what will be the relationship with Modules and Namespaces?
So, as a contrived example, I might lay my project out like:
src/
ArbitraryBoundedContext/
Domain/
// If I have a TON of collab b/w ARs, I'll actually split my domain
// into a "services" module and "model" module.
ParticularDomainService.php
Aggregate/
AggregateRoot.php
HappyChildEntityOfAggregate.php // It happens... keeping it simple here.
AggregateRepository.php // Define interface in the domain.
RelatedValueObject.php
Events/
AggregateRootDidSomeMeaningfulThing.php
AggregateRootDidSomethingTheDomainCaresAbout.php
// This is an example... but if your events are this long...
//you're probably doing too much :)
// Application & UseCases are the same thing really; depends on
// what you want to do. More command-bussy? Usecases are great
// to fit into that paradigm. Simpler bounded context? Keep it simple
// with a service class.
Application/
ApplicationServiceWithAFewMethodsAllInOne.php
SomeFacadeForOtherBoundedContextsToIntegrateWithMe.php
UseCases/
Commands/
DoSomeUseCaseGoodName.php
TightlyFocusedUseCaseClassThatHandlesCommands.php
Infrastructure
Persistance
ImplementationOfAggregateRepository.php
So, the above is just arbitrary and makes sense for me. Again, don't go hunting for the right way to lay your project out. Get a grasp on the concepts and then agree on a structure that you and your team can swallow and reason about.
This went a lot longer and I'm sure I made some mistakes in reasoning, but there it is. Feel free to ask any follow-ups and I'll try to be helpful!
// edit I left out Laravel!
That's honestly the beautiful thing about explicitly declaring an application layer whether it be a big "use-case class" with individual methods to handle different use-cases (similar to a traditional Laravel controller you'd see in a tutorial in the wild) or something more robust like the command-bus examples on Laracasts. Either way, your code is framework agnostic. You defer technical decisions until the last possible moment (or not; your choice.. and that's the point). So, back to Laravel...
Under the above project structure, I treat my routing layer and controller as almost one "HTTP transport facilitation mechanism". I use the framework to process HTTP messages, convert them into some form of "an intention" on my domain (whether it be a Command class or a method call on an application service) and then I catch exceptions from that execution and respond accordingly. If no exception, I'll most likely render a Blade / Twig template that I give a Presenter from my application. Again, whether I use Blade or Twig for a project doesn't matter. The "Presenter" or "Read Model" is the authoritative source of truth for me. Getting it back to the user as an HTTP response is up to the framework and I'm free to choose path of least confusion! :)
A typical controller method in a project like this, for me is:
- Grab inputs from framework to try and ...
- Construct a valid command for my domain that represents a user's intention to do something
- Execute that command against an application service representing use-case of the bounded context
- Catch any exceptions and respond accordingly. This might be a
CommandValidationExceptionthat was thrown as soon as I tried to construct the command or it might be an exception from some business rule / invariant that was broken. - Fall through to whatever the "success case" should be. Usually, this is either going to be "redirect to some other named route" or "render a page" etc.