ADR-0001: Clean Architecture con package by feature¶
Stato: Accettato Data: 2026-05-20
Contesto¶
Dobbiamo decidere come organizzare il codice sorgente del progetto. Le opzioni tradizionali nel mondo Spring sono:
- Package by layer —
controller/,service/,repository/,entity/. - Package by feature —
task/,user/,auth/, ognuno con i propri layer interni. - Hexagonal / Clean Architecture pura — separazione rigida domain/application/infrastructure con porte e adapter.
Il progetto è didattico ma deve riflettere pattern enterprise reali. Vogliamo che lo studente impari un'organizzazione che scala quando il codice cresce.
Decisione¶
Adottiamo package by feature con principi di Clean Architecture applicati in modo pragmatico:
- Ogni feature è un package coeso (
dev.federicocalo.sbfs.task,auth,user, …). - All'interno di una feature: sotto-package per
dto,domain,infrastructurequando la complessità lo giustifica. - Le dipendenze puntano sempre verso il dominio, mai verso l'infrastruttura.
- DTO usano records immutabili.
- Constructor injection ovunque, mai field injection.
- Validation a system boundaries (controller), non distribuita.
Non introduciamo da subito porte/adapter espliciti: lo facciamo solo dove c'è un beneficio concreto (es. integrazione con sistemi esterni nello step 06+).
Conseguenze¶
Positive
- Modifiche a una feature toccano un solo package: rivedere PR più semplice.
- Allineato alle architetture moderne (Spring Modulith, DDD bounded context).
- Permette estrazione futura a microservizio per singola feature senza riorganizzazione globale.
Negative
- All'inizio sembra "vuoto": package con pochi file. Accettabile, cresce nel tempo.
- Richiede disciplina per non scivolare in dipendenze circolari tra feature.
Neutre
- I newcomer abituati a
controller/service/repositorydevono adattarsi: lo step 01 lo motiva esplicitamente.
Alternative valutate¶
- Package by layer — scartata: porta a "service god class" e a PR che toccano 4 directory per una sola feature.
- Hexagonal puro — scartata per ora: overhead concettuale eccessivo per il target didattico. Reintroducibile in step avanzati se utile.