You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The main advantage of Hexagonal Architecture is that it decouples the heart of your application from [Input/Output](https://press.rebus.community/programmingfundamentals/chapter/input-and-output/).
42
+
42
43
I call the heart of the application the `Domain`. This is the area of the app where all the pieces of code represent the problem we are solving. This part must be side-effect-free, it must not rely on any tools, frameworks, or technologies.
43
-
`Output` refers to the tools the application needs to work, such as network calls, database queries, filesystem operations, actual timestamps, or randomness. All `Output` is moved to the infrastructure. `Input` refers to how the domain is exposed to the outside world, for example, it can be a web controller or a CLI command. These pieces of code are moved to the `UserInterface`.
44
+
45
+
`Outputs` refer to the tools the application needs to work, such as network calls, database queries, filesystem operations, actual timestamps, or randomness. All `Outputs` are moved to the infrastructure. `Inputs` refer to how the domain is exposed to the outside world, for example, it can be a web controller or a CLI command. These pieces of code are moved to the `UserInterface`.
44
46
45
47
**Note:** Check out my blog post about Hexagonal Architecture to dive deeper into the subject:
46
48
@@ -63,7 +65,7 @@ api/src/Domain/
63
65
64
66
I am not a big fan of Onion Architecture because I prefer to keep my projects as simple as possible. Having many layers can make maintenance challenging, as it requires aligning the entire team on coupling rules. Even agreeing with yourself can be difficult, so getting several people to agree is often much harder. Here, we follow just one simple rule : `Domain` must **not** use IO
65
67
66
-
At times, I needed to create custom libraries because I couldn’t find any open-source libraries that met my expectations. To avoid coding directly in the `vendor` directory, I introduced a third area called `Libraries` (this area is optional). These libraries can be used in both the `Domain` and `Infrastructure` layers, but their usage must not violate the coupling rules defined for those areas.
68
+
At times, I needed to create custom libraries because I couldn’t find any open-source libraries that met my expectations. To avoid coding directly in the `vendor` directory, I introduced a third area called `Libraries` (this area is optional). These libraries can be used in both the `Domain`, `UserInterface` and `Infrastructure` layers, but their usage must not violate the coupling rules defined for those areas.
67
69
68
70
```bash
69
71
tree src/Domain/ -L 1
@@ -74,7 +76,7 @@ api/src/Domain/
74
76
└── UserInterface
75
77
```
76
78
77
-
**Coupling rules:**`Libraries` must **not** depend on `Domain` and `Infrastructure`
79
+
**Coupling rules:**`Libraries` must **not** depend on `Domain`, `UserInterface` and `Infrastructure`
78
80
79
81
Finally, I created a sub-area called Application within the Infrastructure layer. It contains all the code needed to have the application up and running, such as framework code (Symfony kernel and framework customizations), data fixtures, and migrations. In the following example, `Exception` and `Security` folders contain framework customizations.
**Note :** Looking back, I won't keep the folder in infra. All code related to framework customization should go into a dedicated folder called framework in the `Libraries` folder, whereas `Fixtures` and `Migrations` can remain at the root of the infrastructure folder.## Focus on the business
94
+
**Note :** Looking back, I won't keep the folder in infra. All code related to framework customization should go into a dedicated folder called framework in the `Libraries` folder, whereas `Fixtures` and `Migrations` can remain at the root of the infrastructure folder.
93
95
94
-
A really important aspect for me is organizing the codebase around business concepts. I avoid naming folders and classes based on technical patterns like Entity, ValueObject, or Repository, and especially not Provider, DataMapper, or Form. Non-technical people should be able to understand the purpose of a class simply by its name.
96
+
## Focus on the business
97
+
98
+
A really important aspect for me is organizing the codebase around business concepts. I avoid naming folders and classes based on technical patterns like `Entity`, `ValueObject`, or `Repository`, and especially not `Provider`, `DataMapper`, or `Form`. Non-technical people should be able to understand the purpose of a class simply by its name.
95
99
96
100
### Domain
97
101
@@ -106,19 +110,16 @@ Since I avoided using technical terms to name folders, it's easy to imagine that
106
110
107
111
```bash
108
112
tree src/Domain/Map -L 1
109
-
├── CartographersAllowedToEditMap.php // Value object
In this folder, we have all the code necessary to design the `Map` aggregate. As you can see, I didn’t organize it by design patterns like `ValueObject`, `Entity`, or something else.
0 commit comments