Guida alla modularizzazione delle app per Android

Un progetto con più moduli Gradle è noto come progetto multimodulo. Questa guida illustra le best practice e i pattern consigliati per lo sviluppo di app Android multimodulo.

Il problema del codebase in crescita

In un codebase in continua crescita, scalabilità, leggibilità e qualità complessiva del codice diminuiscono spesso nel tempo. Ciò è dovuto all'aumento delle dimensioni del codebase senza che i manutentori adottino misure attive per applicare una struttura facilmente gestibile. La modularizzazione è un mezzo per strutturare il tuo codebase in modo da migliorare la manutenibilità e aiutare a evitare questi problemi.

Che cos'è la modularizzazione?

La modularizzazione è una pratica che consiste nell'organizzare un codebase in parti a basso accoppiamento e contenute a sé stanti. Ogni parte è un modulo. Ogni modulo è indipendente e ha uno scopo chiaro. Dividendo un problema in sottoproblemi più piccoli e più facili da risolvere, riduci la complessità della progettazione e della gestione di un grande sistema.

Figura 1: grafico delle dipendenze di un codebase multimodulo di esempio

Vantaggi della modularizzazione

I vantaggi della modularizzazione sono molti, anche se ciascuno incentrato sul miglioramento della manutenibilità e della qualità complessiva di un codebase. La tabella seguente riepiloga i vantaggi principali.

Vantaggio Riepilogo
Riutilizzabilità La modularizzazione offre opportunità di condivisione del codice e creazione di più app dalla stessa base. I moduli sono efficaci componenti di base. Le app devono essere una somma delle loro funzionalità, dove queste ultime sono organizzate in moduli separati. La funzionalità fornita da un determinato modulo può essere attivata o meno in una determinata app. Ad esempio, :feature:news può far parte della versione completa dell'app Wear, ma non della versione demo.
Rigoroso controllo della visibilità I moduli ti consentono di controllare facilmente ciò che esponi ad altre parti del tuo codebase. Puoi contrassegnare come internal o private tutto tranne la tua interfaccia pubblica per evitare che venga utilizzata al di fuori del modulo.
Pubblicazione personalizzabile Play Feature Delivery utilizza le funzionalità avanzate degli app bundle, consentendoti di offrire determinate funzionalità della tua app in base alle condizioni oppure on demand.

I vantaggi di cui sopra sono raggiungibili solo con un codebase modulare. I seguenti vantaggi potrebbero essere ottenuti con altre tecniche, ma la modularizzazione può aiutarti ad applicarle ancora di più.

Vantaggio Riepilogo
Scalabilità In un codebase strettamente accoppiato, una singola modifica può innescare una cascata di alterazioni in parti di codice apparentemente non correlate. Un progetto adeguatamente modularizzato adotta il principio della separazione dei problemi e pertanto limita l'accoppiamento. In questo modo i collaboratori possono contare su una maggiore autonomia.
Proprietà Oltre ad abilitare l'autonomia, i moduli possono essere utilizzati anche per rafforzare la responsabilizzazione. Un modulo può avere un proprietario dedicato che sia responsabile della manutenzione del codice, della correzione dei bug, dell'aggiunta di test e della revisione delle modifiche.
Incapsulamento Incapsulamento significa che ogni parte del codice deve conoscere la minima quantità possibile di conoscenze sulle altre parti. Il codice isolato è più facile da leggere e capire.
Testabilità La verificabilità caratterizza quanto è facile testare il tuo codice. Un codice testabile è un codice in cui i componenti possono essere facilmente testati in isolamento.
Ora build Alcune funzionalità di Gradle, come build incrementale, build cache o build parallela, possono sfruttare la modularità per migliorare le prestazioni della build.

Insidie comuni

La granularità del codebase corrisponde alla misura in cui è composto dai moduli. Un codebase più granulare contiene un numero maggiore di moduli più piccoli. Quando progetti un codebase modulare, devi decidere un livello di granularità. Per farlo, tieni conto delle dimensioni del codebase e della relativa complessità. Un'eccessiva granularità ridurrà il carico di lavoro, mentre un'eccessiva granularità ridurrà i vantaggi della modularizzazione.

Ecco alcuni errori comuni:

  • Troppo granulare: ogni modulo comporta un certo overhead sotto forma di maggiore complessità della build e codice boilerplate. Una configurazione di build complessa rende difficile mantenere coerenti le configurazioni tra i moduli. Troppo codice boilerplate comporta un codebase ingombrante e difficile da gestire. Se l'overhead contrasta i miglioramenti della scalabilità, ti consigliamo di consolidare alcuni moduli.
  • Troppo granulare: al contrario, se i tuoi moduli diventano troppo grandi, è possibile che finisca con un altro monolite e non i vantaggi che offre la modularità. Ad esempio, in un piccolo progetto va bene inserire il livello dati all'interno di un singolo modulo. Tuttavia, man mano che l'azienda cresce, potrebbe essere necessario separare i repository e le origini dati in moduli autonomi.
  • Troppo complesso: non sempre ha senso modularizzare il progetto. Un fattore dominante è la dimensione del codebase. Se non prevedi che il tuo progetto cresca oltre una determinata soglia, la scalabilità e i guadagni di tempo di creazione non vengono applicati.

La modularizzazione è la tecnica giusta per me?

Se hai bisogno dei vantaggi della riusabilità, del rigoroso controllo della visibilità o dell'utilizzo di Play Feature Delivery, la modularizzazione è una necessità. Se non intendi farlo, ma vuoi comunque trarre vantaggio da una migliore scalabilità, proprietà, incapsulamento o tempi di build, la modularizzazione è qualcosa che vale la pena prendere in considerazione.

Samples