Skip to Content

Richiamo all’architettura dell’app Flutter

Obiettivo

Strutturare correttamente il progetto per facilitare manutenzione, riuso, testing e scalabilità.


Perché serve un’architettura?

  • Codice più leggibile
  • Facile separare UI e logica
  • Collaborazione tra team
  • Scalabilità e test automatizzati

Struttura a cartelle base

CartellaContenuto
lib/screens/Le schermate (UI)
lib/models/Strutture dati (classi, DTO, entity)
lib/services/Chiamate API, DB, Firebase
lib/widgets/Componenti riutilizzabili
lib/providers/Logica di stato se si usa Provider

In alternativa: lib/feature/nome/ per struttura modulare (feature-based)


Separation of concerns

Ogni parte del codice ha un singolo scopo:

LivelloResponsabilità
UI (screens)Visualizza e riceve input
LogicGestisce eventi, stato, validazione
Data layerInterroga API, DB, storage

Clean Architecture base

StratoDescrizione
PresentationUI + ViewModel
DomainEntità, UseCases, logica pura
DataRepository, sorgente dati (API, DB, Firebase)

Vantaggi:

  • Codice testabile
  • Decoupling
  • Manutenibilità nel lungo periodo

Esempio pratica: app Note

CartellaCosa contiene
screens/note_list.dartUI della lista note
models/note.dartModello Note
services/note_api.dartFunzione per caricare/salvare
providers/note_provider.dartLogica con ChangeNotifier

Consigli

Usa extension o helper per pulire la UI

  • Extension: aggiungi funzionalità a tipi esistenti per scrivere codice più leggibile.
extension Spacing on num { SizedBox get h => SizedBox(height: toDouble()); SizedBox get w => SizedBox(width: toDouble()); } Column( children: [ Text('Titolo'), 16.h, // invece di SizedBox(height: 16) Text('Descrizione'), ], )
  • Helper: funzioni riutilizzabili per widget personalizzati.
//File: nome_helper.dart Widget customButton(String label, VoidCallback onPressed) { return ElevatedButton( onPressed: onPressed, child: Text(label.toUpperCase()), ); } //File:screen customButton("Login", () => print("Premuto"));

Non mischiare setState, Provider, Bloc, ecc.

Usare troppi approcci per la gestione dello stato nello stesso progetto crea confusione, rende il debug più difficile e complica l’onboarding di altri sviluppatori. Scegli un paradigma coerente per tutto il progetto, ed eventualmente usa setState solo per widget locali molto semplici.

  • Nomina coerente (es. NoteService, NoteScreen, NoteModel)
  • Ogni file dovrebbe contenere una sola responsabilità