Skip to content

Commit 10e9706

Browse files
committed
fixes glitches
1 parent 4c74385 commit 10e9706

File tree

1 file changed

+21
-18
lines changed
  • content/blog/how-did-I-organize-my-last-symfony-project

1 file changed

+21
-18
lines changed

content/blog/how-did-I-organize-my-last-symfony-project/index.en.md

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ In the following sections, we will explore how I organized the application sourc
3939
> https://en.wikipedia.org/wiki/Hexagonal_architecture_%28software%29
4040
4141
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+
4243
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`.
4446

4547
**Note:** Check out my blog post about Hexagonal Architecture to dive deeper into the subject:
4648

@@ -63,7 +65,7 @@ api/src/Domain/
6365

6466
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
6567

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.
6769

6870
```bash
6971
tree src/Domain/ -L 1
@@ -74,7 +76,7 @@ api/src/Domain/
7476
└── UserInterface
7577
```
7678

77-
**Coupling rules:** `Libraries` must **not** depend on `Domain` and `Infrastructure`
79+
**Coupling rules:** `Libraries` must **not** depend on `Domain`, `UserInterface` and `Infrastructure`
7880

7981
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.
8082

@@ -89,9 +91,11 @@ api/src/Infrastructure/Application
8991
└── Kernel
9092
```
9193

92-
**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.
9395

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.
9599

96100
### Domain
97101

@@ -106,19 +110,16 @@ Since I avoided using technical terms to name folders, it's easy to imagine that
106110

107111
```bash
108112
tree src/Domain/Map -L 1
109-
├── CartographersAllowedToEditMap.php // Value object
110-
├── Description.php // Value object
111-
├── MapCreated.php // Event
112-
├── MapId.php // Value object
113-
├── MapName.php // Value object
114-
├── Map.php // Root aggregate
115-
├── Maps.php // Repository interface
116-
├── Marker // All classes to design Marker entity
117-
├── MarkerAddedToMap.php // Event
118-
├── MarkerDeletedFromMap.php // Event
119-
├── MarkerEditedOnMap.php // Event
120-
├── UnknownMap.php // Exception
121-
└── UseCase // Use cases orchestration
113+
├── CartographersAllowedToEditMap.php // ValueObject
114+
├── Description.php // ValueObject
115+
├── MapCreated.php // Event
116+
├── MapId.php // ValueObject
117+
├── MapName.php // ValueObject
118+
├── Map.php // Aggregate root
119+
├── Maps.php // Interface Repository
120+
├── Marker // Dossier pour Marker
121+
├── MarkerAddedToMap.php // Event
122+
└── UseCase // Orchestration des cas d’usage
122123
```
123124

124125
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.
@@ -143,6 +144,8 @@ api/src/Infrastructure
143144
└── PostgreSqlMaps.php
144145
```
145146

147+
### UserInterface
148+
146149
```bash
147150
tree src/UserInterface -L 1
148151
api/src/UserInterface

0 commit comments

Comments
 (0)