Architettura software .NET per smettere di rincorrere il codice e tornare a governarlo
Qui trovi come usare design pattern, DDD e CQRS per prendere decisioni strutturali migliori, tagliare debito tecnico inutile e costruire software .NET che non si sbriciola appena cambia il dominio.
I design pattern non sono ricette da copiare: sono risposte a problemi reali
Ogni volta che vedo un progetto con classi chiamate FactoryManagerHelperService ho la certezza di trovarmi davanti a un uso del pattern sbagliato: qualcuno ha imparato il nome senza capire il problema che quel pattern dovrebbe risolvere.
Un design pattern è una soluzione consolidata a un problema che si ripete.
Il Repository non esiste per soddisfare un requisito architetturale astratto: esiste perché separare la logica di dominio dall'accesso ai dati rende il codice testabile, sostituibile e leggibile da chiunque conosca il pattern.
Se nel tuo progetto nessuno sa spiegare perché esiste un certo layer, quel layer probabilmente non dovrebbe esistere.
Il mio approccio ai pattern è pragmatico.
Prima capisco quale problema c'è, poi valuto se un pattern noto lo risolve meglio di una soluzione ad hoc.
Molto spesso la risposta è sì: non perché i pattern siano magia, ma perché rappresentano il risultato di decenni di errori che altri hanno già fatto.
Questa categoria esiste per aiutarti a capire i pattern come strumenti di pensiero, non come checklist.
Quando sai perché Repository, CQRS, Mediator o Specification esistono, smetti di applicarli meccanicamente e inizi a usarli dove portano valore reale.
Quando l'architettura diventa un problema economico
L'architettura software non è un tema accademico.
È un problema economico che si manifesta nel tempo.
Un sistema progettato male non crolla il giorno uno.
Regge.
Poi rallenta.
Poi ogni modifica richiede il doppio del tempo.
Poi le persone chiave diventano insostituibili perché solo loro conoscono i punti oscuri del codice.
Poi il testing diventa impossibile.
Poi arriva il refactoring di emergenza, che di solito costa cinque volte quello che sarebbe costato fare le cose bene all'inizio.
Quando un team mi chiede aiuto su un sistema in difficoltà, quasi sempre trovo le stesse radici: accoppiamento eccessivo tra componenti, assenza di confini chiari tra dominio e infrastruttura, logica di business dispersa ovunque, nessuna coerenza nei nomi.
Sono tutti sintomi che indicano l'assenza di un modello architetturale consapevole.
I pattern non eliminano la complessità del dominio.
La rendono governabile.
E la differenza tra complessità governabile e complessità caotica è spesso la differenza tra un'azienda che riesce a rilasciare e una che ha paura di cambiare qualcosa.
| Sintomo | Causa archittetturale frequente | Intervento con pattern |
|---|---|---|
| Ogni modifica rompe qualcosa di inaspettato | Accoppiamento forte tra moduli | Separazione con Repository, Mediator, eventi di dominio |
| Nessuno riesce a testare le funzioni chiave | Logica mescolata con infrastruttura | Clean Architecture, Dependency Inversion |
| I bug si moltiplicano sotto stress | Stato condiviso e mancanza di confini | Aggregate Root, Bounded Context, CQRS |
| Il team rallenta man mano che il sistema cresce | Nessun linguaggio condiviso sul codice | DDD e Ubiquitous Language |
DDD, CQRS e Clean Architecture: quando usarli e quando evitarli
Uno degli errori più costosi che vedo nei team è adottare DDD, CQRS o Clean Architecture perché «si fa così» o perché li hanno visti in un talk su YouTube.
Questi sono pattern ad alta complessità strutturale: portano benefici reali solo quando il dominio li giustifica.
DDD ha senso quando la complessità del sistema sta nel dominio di business, non nell'infrastruttura. Se stai costruendo un sistema di gestione contratti, workflow di approvazione o logica di pricing complessa, DDD ti dà gli strumenti per modellare quel dominio in modo esplicito e condiviso con il business. Se stai costruendo un CRUD con qualche validazione, DDD è overkill.
CQRS ha senso quando i modelli di lettura e scrittura hanno requisiti molto diversi: performance, proiezioni denormalizzate, scalabilità asimmetrica. Se applichi CQRS a un sistema dove lettura e scrittura hanno la stessa semplicità, stai aggiungendo layer senza aggiungere valore.
Clean Architecture ha senso quando vuoi che il dominio non dipenda dall'infrastruttura e che il sistema sia testabile indipendentemente dal database, dal framework o dall'UI. Ma richiede disciplina: senza una comprensione profonda delle dipendenze tra layer, diventa un labirinto di interfacce inutili.
Il principio che uso sempre è: applica la complessità strutturale solo dove la complessità del problema la giustifica.
Il codice semplice che funziona è meglio del codice complesso che segue un pattern.
Come introdurre i pattern in un progetto esistente senza bloccare il team
Nessuno ha il lusso di riscrivere tutto da zero.
I pattern devono entrare nei sistemi esistenti in modo incrementale, senza bloccare le consegne e senza terrorizzare il team.
Il mio approccio è sempre per priorità di rischio e impatto.
Non inizio dal layer più bello da refactorizzare: inizio dal codice che causa più problemi, che nessuno vuole toccare, che rallenta ogni sprint.
Spesso è la logica di business dispersa nei controller, oppure l'accesso diretto al database dappertutto, oppure una classe da tremila righe che fa tutto.
Il primo passo non è introdurre un pattern: è capire dove il codice produce attrito e perché.
Solo dopo si sceglie lo strumento.
A volte basta estrarre un metodo.
A volte serve un Repository.
A volte il problema è un Bounded Context non riconosciuto che mescola responsabilità incompatibili.
Quello che non funziona è imporre un'architettura dall'alto e aspettarsi che il team la rispetti senza capirla.
I pattern si adottano quando il team capisce il problema che risolvono.
La formazione è parte del processo, non un prerequisito separato.
Come leggere gli articoli di questa categoria
Gli articoli che trovi qui non sono tutorial che ti insegnano a implementare un pattern in venti minuti.
Sono analisi di problemi reali, con il ragionamento che porta alla scelta di una certa struttura e le conseguenze che quella scelta produce nel tempo.
Alcuni articoli partono da un sintomo: un sistema che non scala, un test impossibile da scrivere, una funzione che nessuno riesce a modificare senza paura.
Da lì arrivano al pattern che risolve quel problema specifico, spiegando perché funziona e dove smette di funzionare.
Se vuoi usare questa categoria nel modo più efficace, ti consiglio di non leggerla in ordine alfabetico per pattern.
Parti dal sintomo che riconosci nel tuo sistema, trova l'articolo che lo affronta, capisce il ragionamento e poi valuta se il contesto è abbastanza simile da rendere applicabile la stessa soluzione.
I pattern non si copiano.
Si capiscono e si adattano.
Analisi, casi e articoli su design pattern, DDD, CQRS e architettura .NET
11 articoli trovatiClean Architecture in C#: struttura un progetto che regge davvero alla scala
Come implementare Clean Architecture in C# senza dogmi. Struttura reale, dipendenze tra layer, casi utili e limiti da conoscere in .NET.
7 pattern architetturali per annientare il debito tecnico
Il 90% dei progetti accumula debito perché copia architetture senza contesto. 7 criteri per scegliere pattern che evitano rallentamenti.
Debito tecnico nel software: guida completa alla gestione e risoluzione
Il debito tecnico rallenta i team e genera bug. Scopri cause, impatti e strategie per gestirlo e risolverlo senza riscrivere tutto.
Il pattern Unit of Work spiegato per chi vuole scrivere codice che non tradisce
Bug sparsi? Salvataggi senza logica? Il pattern Unit of Work ti salva prima che sia troppo tardi. Scopri come implementarlo con Entity Framework Core.
Design Pattern in C#: trasforma il caos del codice in architetture che resistono al tempo
Il segreto delle architetture che evolvono: padroneggia i Design Pattern in C#. Scrivi meno, progetta meglio.
Perché quello che sto per dirti potrebbe salvare il tuo team di sviluppo (e la tua azienda) dal collasso tecnico che nessuno vede arrivare
Scopri come prevenire il collasso tecnico e come proteggere il tuo team di sviluppo da architetture complesse, prima che blocchino la tua azienda.
Domain Driven Design: il modo più veloce per scrivere codice testabile ed allineato alla realtà
Il Domain Driven Design ti aiuta a modellare il dominio, ridurre la confusione architetturale e ottenere codice chiaro e verificabile.
Il pattern Singleton è un alleato o un sabotatore? In pochi sanno usarlo e tu sarai uno di loro
Il pattern Singleton funziona solo se lo progetti bene. Scopri come usarlo in C# in modo sicuro, chiaro e senza gli errori tipici di chi improvvisa.
CQRS non è solo un pattern: è la svolta che stavi cercando
Ti sei mai chiesto perché il tuo codice diventa ingestibile? CQRS è la risposta che cercavi. Scoprilo ora e rivoluziona il tuo modo di progettare.
Come l'architettura CQRS può portare a nuovi livelli le tue applicazioni
Crea applicazioni .NET super veloci con questo potente pattern e l'architettura CQRS!
Quando l'architettura smette di essere teoria
L'architettura smette di essere teoria quando il software deve essere mantenuto per anni, coordinato da piu persone e modificato senza paura. In quel momento pattern, confini e responsabilita non servono a fare bella figura: servono a evitare costi nascosti, regressioni e decisioni improvvisate.
Domande frequenti
I design pattern sono soluzioni consolidate a problemi ricorrenti nella progettazione del software. Non vanno applicati per abitudine, ma quando il problema che risolvono e effettivamente presente: complessita nella gestione delle dipendenze, accoppiamento eccessivo tra moduli, logica duplicata. Usarli a prescindere aumenta la complessita invece di ridurla.
I design pattern, come Singleton, Repository o Factory, riguardano la struttura a livello di classi e componenti. I pattern architetturali, come CQRS, DDD o Clean Architecture, riguardano l'organizzazione dell'intero sistema: come i layer si relazionano, dove risiedono le responsabilita, come i dati fluiscono. I primi si usano dentro i secondi.
Domain-Driven Design in .NET si applica strutturando il codice attorno al dominio di business: entita, value object, aggregati e repository rispecchiano il linguaggio del business. In pratica significa scegliere nomi significativi per classi e metodi, isolare la logica di dominio dai dettagli infrastrutturali e costruire un bounded context chiaro prima di pensare ai pattern tecnici.
No. CQRS separa i modelli di lettura e scrittura e puo essere utile anche in forma semplice, senza Event Sourcing. Event Sourcing aggiunge la persistenza degli eventi come fonte di verita invece dello stato corrente: e una complessita significativa che si giustifica solo quando la storia delle operazioni ha valore di business autonomo. Combinarli senza un motivo solido crea overhead senza benefici.
Fonti e riferimenti
Martin Fowler, Patterns of Enterprise Application Architecture
Il testo di riferimento assoluto per chi lavora su sistemi enterprise. Fowler cataloga i pattern con un rigore che pochi autori hanno eguagliato. Lo consiglio non per memorizzare le ricette, ma per capire il ragionamento che sta dietro ogni scelta strutturale: perche un certo confine esiste, quando diventa un vincolo e quando una liberazione.
Martin Fowler, Patterns of Enterprise Application Architecture
Eric Evans, Domain-Driven Design
Il libro che ha cambiato il modo in cui i team tecnici parlano con il business. DDD non e una checklist di classi da creare, ma un modo di costruire modelli che riflettono davvero il dominio. Lo cito perche ogni volta che un progetto diventa difficile da spiegare, il problema e quasi sempre nell'assenza di un linguaggio condiviso tra chi sviluppa e chi decide.










