## Buone pratiche di modularizzazione

### Elementi di modularizzazione

La modularizzazione di un software rappresenta uno strumento indispensabile per governare la complessità e aumentare la manutenibilità dello stesso. Questo è vero anche per i progetti realizzati in modalità model-driven: in questo caso, ovvimente, il concetto di "modularizzabilità" si applica a livello di modelli.

I punti di moularizzabilità messi a disposizione da Guigen sono i seguenti:

- possibilità di raggruppare più ContentPanel in AppModule
- possibilità di definire package di tipi, raggruppandoli sotto uno stesso TypeNamespace
- possibilità di raggruppare un insieme di ApplicationData in uno stesso AppDataGroup
- possibilità di definire un frammento di struttura UI, tramite l'elemento PanelDef per poi riutilizzarlo in più ContentPanel

Questa modularizzazione si concretizza nella creazione di più file di modello, interconnessi secondo quanto descritto qui.

Di seguito vengono illustrate alcune buone pratiche per la gestione modulare di un progetto guigen.

### AppModule

#### Buone pratiche di strutturazione degli AppModule

Non è semplice definire un insieme di regole esaustive che permettano di organizzare al meglio gli AppModule che costituiscono l'applicativo: la scelta del come raggruppare le differenti schermate dipende molto dalla tipologia del progetto ma, talvolta, anche dall'organizzazione del gruppo di lavoro. Poichè gli AppModule non sono altro che gruppi di ContentPanel che hanno qualcosa in comune, è opportuno evidenziare uali possono essere i criteri di coesione che possono portare a raggruppare un insieme di ContentPanel.

##### Un AppModule = una funzionalità

Questo approccio prevede la collocazione in uno stesso AppModule di tutti i ContentPanel che realizzano una sola funzionalità. Esempio: funzione di gestione CRUD di un dato di business. L'AppModule potrebbe contenere ad esempio:

- un ContentPanel per i filtri di ricerca
- un ContentPanel per i risultati di ricerca
- un ContentPanel per il dettaglio del singolo elemento, con possibilità di editing

Si presta bene per quelle funzionalità che non sono realizzabili mediante un singolo ContentPanel.

##### Un AppModule = un sottosistema o profilo funzionale

Questo approccio prevede la collocazione in uno stesso AppModule di tutti i ContentPanel che realizzano un insieme di funzionalità (sottosistema) o le funzionalità legate ad un particolare profilo utente. L'AppModule potrebbe contenere uno o più ContentPanel per ogni funzonalità.

#### Cattive pratiche di strutturazione

Esistono poi alcuni esempi negativi (bad practice) di strutturazione di AppModule:

- un AppModule = un ContentPanel: la tentazione di una simile suddivisione potrebbe derivare dalla volontà di rendere possibile l'assegnazione dello sviluppo della singola schermata ad uno specifico sviluppatore. Raramente però una funzionalità è costituita da un singolo ContentPanel pertanto questo approccio eccessivamente "granulare" ha l'unico effetto di moltiplicare il numero di file del progetto e le dipendenze tra i vari sotto-modelli.
- Un unico AppModule: questo approccio tipicamente nasce in quei progetti in cui non viene fatta una macroanalisi funzionale iniziale che possa evidenziare una modularizzazione di tipo funzionale. L'adozione di un simile approccio mostra i suoi limiti nel momento in cui l'applicazione prende corpo le funzioni aumentano in numero, rendendo molto difficile lo sviluppo parallelo del progetto.
- AppModule privi di connotazione esplicita: se non si individua la connotazione che caratterizza un AppModule (ad esempio secondo le best practices di cui sopra) potrebbe veriifcarsi una mera suddivisione numerica dei ContentPanel nei vari AppModule (es. module1, module2, ...) che non dà grossi vantaggi rispetto ad una gestione piatta.

#### Effetti sul codice generato della strutturazione degli AppModule

La strutturazione delle schermate in AppModule comporta effetti sia sul codice generato, sia sulle configurazioni, sia sulle URL dell'applicazione.

Per quanto riguarda il codice generato vi sono i seguenti effetti:

- la classi java delle action relative ai ContentPanel sono generate tutte all'interno di uno stesso package (che ha il nome dell'AppModule), sotto il package `it.csi.[prodotto].[componente].presentation`
- la classi java del model relativi ai ContentPanel sono generate tutte all'interno di uno stesso package (che ha il nome dell'AppModule), sotto il package `it.csi.[prodotto].[componente].dto`
- la classi java dei bean di spring relativi ai ContentPanel sono generate tutte all'interno di uno stesso package (che ha il nome dell'AppModule), sotto il package `it.csi.[prodotto].[componente].business`

Per quanto riguarda l'organizzazione in namespace struts, occorre ancora dire che ciascun AppModule può essere marcato come secure. A fronte dell'eventuale presenza di questa impostazione e a fronte del nome dell'AppModule si hanno i seguenti effetti:

- l'url di esposizione della action corrispondente al singolo ContentPanel è:
  - `/[contesto]/base/[modulo]/[contentPanel].do` se il modulo non è marcato come secure
  - `/[contesto]/secure/[modulo]/[contentPanel].do` se il modulo è marcato come secure

Aggiungendo che tutte le action globali sono di default sotto il namespace secure (es. `HomePage.do`, `Logout.do`) questa strutturazione in namespace permette la realizzazione di esposizioni più mirate tramite il web server, ad esempio permettendo di proteggere con Shibboleth solo alcune action e altre no).

Per quanto riguarda la configurazione l'unico effetto sta nella generazione di un file di configurazione di struts per ciascun namespace, e pertanto per ciascun AppModule.

### TypeNamespace

#### Buone pratiche di strutturazione dei TypeNamespacee

Le buone pratiche di strutturazione dei package di tipi in un qualsiasi linguaggio di programmazione si applicano anche al contesto dei modelli. Occorre tener presente che, a differenza dei ContentPanel de degli AppModule, i tipi sono utilizzabili in molte funzionalità. D'altra parte è vero che i tipi utilizzati in guigen sono destinati a contenere il model delle schermate e pertanto alcuni ComplexType sono specifici di una singola schermata.

- mettere in uno stesso TypeNamespace tutti i tipi specifici di un certo sottoinsieme di dati di business. Questo TypeNamespace tipicamente viene riusato in più moduli di applicazione.
- mettere in uno stesso TypeNamespace tutti i tipi associati alle schermate di un AppModule. Tipicamente questi tipi possono a loro volta utilizzare come membri tipi più generici (quelli del punto precedente, ad esempio)

#### Effetti sul codice generato

L'effetto dell'appartenenza di un ComplexType ad uno specifico TypeNamespace è che la classe corrispondente viene generata in un sotto-package del package dto che ha il nome del TypeNamespace.

### AppDataGroup

#### Buone pratiche di strutturazione degli AppDataGroup

Gli ApplicationData rappresentano il corrispettivo nel mondo MDD di quello che sono le variabili applicative nella programmazione tradizionale. Pertanto le pratiche di buona strutturazione sono almeno in parte le stesse che si adottano per la definizione delle variabili nella propria applicazione.

La suddivisione in AppDataGroup rappresenta solo un raggruppamento logico dell ApplicationData utile a governare meglio la numerosità degli ApplicationData. Alcune buone pratiche di organizzazione sono:

- un AppDataGroup per variabili a scope globale, trasversale a tutte le funzionalità
- un AppDataGroup per ogni Appmodule, contenente tutti gli ApplicationData utilizzati nelle schermate di quell' AppModule

#### Effetti sul codice generato

Non vi sono effetti sul codice generato in quanto il generatore non genera nulla a fronte dell'esistenza di un ApplicationData, ma genera solo codice a fronte dell'utilizzo che di tali elementi viene fatto nelle schermate.