File & directory structure for Apparat modules (DDD)
.
|-- composer.json
|-- src
| `-- <PACKAGE>
| |-- Application
| | |-- CommandHandlers
| | `-- Service
| |-- Domain
| | |-- Command
| | | |-- CommandBusInterface.php
| | | `-- CommandHandlerInterface.php
| | |-- Model
| | | |-- Entity.php
| | | `-- EntityRepository.php (Interface)
| | |-- ValueObject.php
| | `-- DTO.php
| `-- Framework
| |-- Http¹
| `-- Persistence²
`-- tests
¹ Arbitrary number of primary ports (may e.g. be Api
, Cli
, Rest
, etc.)
² Arbitrary number of secondary ports
Namespaces
Domain
- Defining the behaviour and constraints of the application
- Business logic ("Core domain")
- Entities
- Value objects
- Validators
- Specifications
- Supporting domain logic
- Domain services
- Representing, orchestrating and executing domain tasks and operations
- Stateless
- Domain Events
- Use-Cases / Commands (definitions of what actions an be taken on the applications)
- Domain services
- Framework agnostic / infrastructure independent
- Providing interfaces ("ports") for implementations ("adapters"), e.g. a repository interface
- No external dependencies³
- Must be run from the
Application
namespace - Only domain logic changes should ever affect this namespace
³ Dependencies to 3rd-party libraries might be OK under certain circumstances:
If it's something that you would write in your own domain code, and that would make sense to extract into some reusable code, and that can be extracted into a reusable library, then you might as well depend on a library that does the same thing, but that happens to have been written by someone else.
Application
- Main entry point
- Orchestrates the use of
Domain
layer entities - Adapts requests from the
Framework
layer to theDomain
layer - Handles use-cases / commands
- Dispatches domain events raised by the
Domain
layer - Primary point of integration
- Application level configuration
- Dependency injection configuration
- Abstract base classes
- Providing shared functionality
- No domain or port logic
- To be extended by domain or port classes, e.g.
- Entity base class (
Domain
) - Controller base (
Ports
)
- Entity base class (
- Application services
- Middleware between the outside world and the domain logic
- Transforming commands from the outside to domain instructions
- Possibly having dependencies (e.g. Framework)
- Communication using DTOs (Data Transfer Objects)
- Service providers
- Translating primary port signals (HTTP, API, Cli, REST, etc.) to domain service calls
- Connecting the domain with the infrastructure (binding secondary adapters to domain interfaces)
Framework
- Integration of 3rd-party libraries (e.g. everything composer pulls in)
- Adapts requests from the outside world to the
Application
layer- Accepting HTTP requests
- Collecting user data
- Routing to a Controller etc.
- Calling an application use-case, passing on user data and make the
Application
layer handle the use-case
- Implementing
Application
interfaces - Primary Ports / "Driving" Adapters
- Connecting the application to "The Outer World"
- Controllers / MVC implementations
- e.g.
Http
/Api
/Cli
/Rest
...
- Secondary Ports / "Driven" Adapters
- Connecting the application to the local infrastructure
- Storage, databases (e.g. repository implementations), etc.
Structure before DDD reorganization:
.
|-- README.md
|-- composer.json
|-- phpunit.php
|-- phpunit.xml.dist
|-- src
| |-- Resource
| | |-- ExceptionInterface.php
| | |-- File
| | | |-- CommonMark.php
| | | |-- Exception
| | | | |-- InvalidArgument.php
| | | | `-- Runtime.php
| | | |-- ExceptionInterface.php
| | | |-- Frontmatter
| | | | `-- Yaml
| | | | |-- CommonMark.php
| | | | `-- Exception
| | | | `-- InvalidArgument.php
| | | |-- FrontmatterInterface.php
| | | |-- Generic.php
| | | |-- Part
| | | | |-- Body
| | | | | |-- CommonMark.php
| | | | | |-- Exception
| | | | | | `-- OutOfBounds.php
| | | | | |-- ExceptionInterface.php
| | | | | |-- Generic.php
| | | | | |-- Text.php
| | | | | `-- Yaml.php
| | | | |-- Body.php
| | | | |-- BodyInterface.php
| | | | |-- Container
| | | | | |-- Choice.php
| | | | | |-- ChoiceInterface.php
| | | | | |-- Exception
| | | | | | |-- InvalidArgument.php
| | | | | | |-- OutOfBounds.php
| | | | | | |-- OutOfRange.php
| | | | | | `-- Runtime.php
| | | | | |-- ExceptionInterface.php
| | | | | |-- Sequence.php
| | | | | `-- SequenceInterface.php
| | | | |-- Container.php
| | | | |-- ContainerInterface.php
| | | | `-- ContainerTrait.php
| | | |-- Part.php
| | | |-- PartInterface.php
| | | |-- Text.php
| | | `-- Yaml.php
| | |-- File.php
| | |-- FileInterface.php
| | `-- Utility.php
| |-- Resource.php
| `-- ResourceInterface.php
`-- test
|-- CommonMarkTest.php
|-- FileTest.php
|-- FrontMarkTest.php
|-- TestBase.php
|-- TextTest.php
|-- YamlTest.php
`-- files
|-- cc0++.txt
|-- cc0.txt
|-- commonmark.md
|-- frontmark.md
|-- invoice.php
`-- invoice.yaml