Posted on: August 27, 2020 04:17 PM
Posted by: Renato
Categories: Laravel ddd Padrao de design
Views: 18623
Laravel is a robust framework. I've been working with since 2016 and until the beginning of 2018 it's standard structure was sufficient for all the projects that I’ve worked with.
So I had a new challenge, we were not sure how big the new project would be, but we already knew that the project should be ready to scale at most as possible when necessary, accepting the entry of new developers on the team without difficulty, perhaps turning each module of the application into a microservice in the future. So I started to learn about software architectural patterns and Domain Driven Design (DDD) approach.
About the DDD
DDD is a software development approach that induces the implementation of a continuous improvement scenario and can be an extremely useful tool to develop quality software that meets customer needs. Created by Eric Evans, he has a book of patterns based on the author experience along of 20 years developing using Object Oriented techniques. The focus of DDD is the Domain, so, to have software that fits perfectly with a specific domain, it is necessary to establish a Ubiquitous Language. In this language we have terms that are part of the daily conversations between business experts and development teams.
To maintain focus on the domain, we need to isolate the domain model from the other parts of the system. One way to do this is to use a layer architecture:
- UI (User Interface): The responsible of displaying information to the user, and accept new data. It could be implemented for web, console, or any presentation technology, present or future;
- Application: This layer has no business logic. It is only a thin layer, responsible for connecting the User Interface to the lower layers;
- Domain: Represents the concepts, rules and business logic. The whole DDD focus is on this layer. Communication with other systems, persistence details, are forwarded to the infrastructure layer;
- Infrastructure: The structural resources that support the upper layers. They are usually the parts of a system responsables of persistence of data, connections to databases, sending messages over networks.
A domain, also known as context or subject, is not necessarily an entity.
Understand domains as an application knowledge domain. In a blog application, we would have Blog with a domain, inside it we would have the business rules to interact with posts, like repositories, models, services … Post, Comment and Category are examples of models that would be inside Blog.
One tip for identifying a domain is when there is more than one entity interacting with it.
Two things you should know before to see our DDD approach:
- The laravel/laravel is yours, it comes with a standard skeleton but you can modify it's default structure for the best approach for your needs. Do not confuse with the laravel/framework in your vendor.
- There is no "right way" to make a DDD structure, it is a continuous process of improvements that you will learn and adapt over time.
Our DDD approach
One thing we keep in mind when we start applying the approach is that we do not want to "fight" with the framework, so all the modifications we’ve made are thinking of the ease of upgrading to the next versions, but trying to leverage the power of the framework within our domain.
At the time I wrote this article, our laravel structure looks like this:
/app
├── /Application
| ├── /Exceptions
| ├── /Middlewares
| ├── /Providers
| ├── /Requests
├── /Domain
| ├── /MyDomainA
| | ├── /Contracts
| | ├── /Entities
| | ├── /Repositories
| | ├── /Services
| ├── /MyDomainB
| | ├── /Contracts
| | ├── /Entities
| | ├── /Jobs
| | ├── /Listeners
| | ├── /Repositories
| | ├── /Services
| ├── .
| ├── .
| ├── .
├── /Infrastructure
| ├── /Contracts
| | ├── BaseRepository.php
| ├── /Jobs
| | ├── Job.php (Abstract)
| ├── /Listeners
| | ├── Listener.php (Abstract)
| ├── /Repositories
| | ├── EloquentRepository.php (Abstract)
| ├── /Scopes
├── /Interfaces
| ├── /Console
| | ├── Kernel.php
| ├── /Http
| | ├── /Controllers
| | ├── /Providers
| | | ├── RouteServiceProvider.php
| | ├── /Resources
| | ├── Kernel.php
/bootstrap
/config
/database
/docker
/public
/resources
/storage
/tests
/vendor
(Other files like .env, artisan, composer.json, etc.)
- https://gist.github.com/lucenarenato/3088ad6501d80dc116a98e03b2d33a92
Now, do you think it's easier to keep this structure for a huge application? I think, because:
- If there is a bug on the X domain, go solve it on the X domain
- There is a new feature do be implemented about Y? go to the Y domain
- A new developer is in charge of domain Z? so go develop inside Z domain
- The domain W could be uncoupled into a microservice? So take the domain W into a microservice (not so easy like saying, but you get it).
Conclusion
As I said before, there is no "right way" to do a structure for DDD. After learning about this software development approach we are now working with the structure shown in this article. But it is an ongoing process, you have to keep evolving to get the best productivity.
If you read this far and wondered “where can I learn more about Domain Driven Design?” I will put below some of the articles and repositories I have read in recent weeks on the subject:
Articles:
- DDD — Introdução a Domain Driven Design (http://www.agileandart.com/2010/07/16/ddd-introducao-a-domain-driven-design/)
- DomainLanguage (http://domainlanguage.com)
- Conciliating Laravel and DDD (http://lorisleiva.com/conciliating-laravel-and-ddd/)
- How to setup Domain Driven Design (DDD) in a Laravel app (https://oliverlundquist.com/2018/03/20/how-to-setup-ddd-in-laravel-app.html)
Repositories:
- https://github.com/ibrunotome/laravel-api-templates
- mikaelmattsson/php-ddd-example
- codecasts/laravel
- emtudo/laravel-vue
- artesaos/migrator
Donate to Site
Renato
Developer