Foreword by Matthias Noback
Preface
- Who Should Read This Book
- DDD and PHP Community
- Summary of Chapters
- Code and Examples
- Acknowledgements
About the Authors
- Carlos Buenosvinos
- Christian Soronellas
- Keyvan Akbary
Getting Started with Domain-Driven Design
- Why Domain-Driven Design Matters
- The Three Pillars of Domain-Driven Design
- Considering Domain-Driven Design
- The Tricky Parts
- Strategical Overview
- Related Movements: Microservices and Self-Contained Systems
- Exercise
- Wrap-Up
Architectural Styles
- Spaghetti Architecture
- Layered Architecture
- DTOs Instead of Model Instances?
- Hexagonal Architecture: Inverting Dependencies
- The Dependency Inversion Principle
- Command Query Responsibility Segregation (CQRS)
- Command Query Separation (CQS)
- Event Sourcing
- Wrap-Up
Value Objects
- Definition
- Exercise
- Value Object vs. Entity
- Exercise
- Currency and Money Example
- Extra Validations for Currency
- Characteristics
- static vs. self
- Exercise
- Basic Types
- Testing Value Objects
- Persisting Value Objects
- Why Doctrine?
- Constructors
- Surrogate Attributes
- Why Use XML Mapping?
- Time to Discuss
- Exercise
- Exercise
- Exercise
- Security
- Wrap-Up
Entities
- Introduction
- Objects vs. Primitive Types
- Identity Operation
- Exercise
- Persisting Entities
- What’s an Annotation?
- Testing Entities
- Validation
- Entities and Domain Events
- Wrap-Up
Services
- Application Services
- Domain Services
- Domain Services and Infrastructure Services
- Testing Domain Services
- Anemic Domain Models vs. Rich Domain Models
- Wrap-Up
Domain Events
- Introduction
- Definition
- Exercise
- Characteristics
- Symfony Event Dispatcher
- Modeling Events
- Why Not the Whole User Entity?
- Doctrine Events
- Persisting Domain Events
- Publishing Events from the Domain Model
- Other Strategy for Publishing Domain Events
- Exercise
- Spreading the News to Remote Bounded Contexts
- Why an Exchange Name?
- Exercise
- Wrap-Up
Modules
- General Overview
- Leverage Modules in PHP
- What about PHAR files?
- Bounded Contexts and Applications
- Can Two Bounded Contexts Be in the Same Application? What about the Other Way Around?
- Structuring Code in Modules
- Should We Place Repositories, Factories, Domain Events, and Services in Their Own Subfolders?
- Wrap-Up
Aggregates
- Introduction
- Key Concepts
- What Is an Aggregate?
- Why Aggregates?
- A Bit of History
- Anatomy of an Aggregate
- Aggregate Design Rules
- Sample Application Service: User and Wishes
- Render the Number of Wishes
- Transactions
- Wrap Up
Factories
- Factory Method on Aggregate Root
- Factory on Service
- Testing Factories
- Wrap-Up
Repositories
- Definition
- Repositories Are Not DAOs
- Collection-Oriented Repositories
- Exercise
- Persistence-Oriented Repository
- Extra Behavior
- Querying Repositories
- Managing Transactions
- Testing Repositories
- Testing Your Services with In-Memory Implementations
- Wrap-Up
Application
- Requests
- Anatomy of an Application Service
- Handling Exceptions
- Is It Bad to Use a Dependency Injection Container?
- Testing Application Services
- Transactions
- Security
- Domain Events
- Command Handlers
- Wrap-Up
Integrating Bounded Contexts
- Integration Through the Data Store
- Integration Relationships
- Implementing Bounded Context Integrations
- Wrap-Up
Appendix: Hexagonal Architecture with PHP
- Introduction
- First Approach
- Repositories and the Persistence Edge
- Decoupling Business and Persistence
- Migrating our Persistence to Redis
- Decouple Business and Web Framework
- Rating an idea using the API
- Console app rating
- Testing Rating an Idea UseCase
- Testing Infrastructure
- Arggg, So Many Dependencies!
- Domain Services and Notification Hexagon Edge
- Let’s Recap
- Hexagonal Architecture
- Key Points
- What’s Next?