DRY nello sviluppo mobile — cos'è, il principio e perché la duplicazione è dannosa

Autore: IT Sectr Pubblicato: 2026-05-12 Tempo di lettura: 8 min

DRY (Don't Repeat Yourself) è un principio fondamentale di sviluppo formulato da Andy Hunt e Dave Thomas nel libro “The Pragmatic Programmer.” Esso stabilisce: ogni parte della conoscenza in un sistema deve avere una rappresentazione unica, inequivocabile e autorevole. Secondo The Pragmatic Programmer, 20th Anniversary Edition, violare DRY significa che modificare un elemento richiede modifiche in decine di punti e ogni frammento mancato diventa una fonte di bug.

Punti chiave

  • DRY è il principio di memorizzare ogni elemento di conoscenza una volta nel sistema, eliminando la duplicazione di codice e dati.
  • La duplicazione aumenta i costi di manutenzione: una modifica in un punto richiede modifiche sincronizzate in tutte le copie.
  • Copy-paste è il principale nemico di DRY: il codice copiato diverge rapidamente e lo sviluppatore dimentica dove sono necessarie altre modifiche.
  • L'astrazione è lo strumento principale di DRY: estrarre frammenti ripetitivi in funzioni, classi o moduli.
  • La Regola del Tre è una regola pratica: se il codice si ripete in tre punti, è tempo di astrarre.

Cos'è DRY?

DRY (Don't Repeat Yourself) è un principio di sviluppo che richiede di memorizzare ogni elemento di conoscenza in un progetto esattamente una volta. Ciò significa che qualsiasi logica, configurazione o metadato deve esistere in un unico punto.

Il termine è stato introdotto da Andy Hunt e Dave Thomas nel 1999 nel libro “The Pragmatic Programmer.” Gli autori hanno definito DRY come “ogni parte della conoscenza deve avere una rappresentazione unica, inequivocabile e autorevole all'interno del sistema.” L'opposto di DRY è l'approccio WET (Write Everything Twice), dove la duplicazione è considerata normale.

Secondo uno studio della University of California, Davis (2019), i progetti con alti livelli di duplicazione del codice spendono il 42% di tempo in più per correggere i bug. Il motivo è che gli sviluppatori devono trovare e modificare tutte le copie dello stesso frammento — e la ricerca manuale porta inevitabilmente a omissioni.

Applica DRY come criterio di qualità del codice. Se noti che lo stesso modello appare tre volte in un progetto — estrailo in un'astrazione senza aspettare una quarta ripetizione.

Differenza tra DRY e principio di responsabilità singola

Il Principio di Responsabilità Singola (SRP) di SOLID stabilisce che una classe dovrebbe avere un solo motivo per cambiare. DRY è più ampio: copre non solo le classi, ma anche dati, configurazione, documentazione e persino regole di business. SRP riguarda i confini di responsabilità; DRY riguarda la prevenzione della copia.

Nello sviluppo mobile, questa distinzione è particolarmente evidente. Se la stessa regola di business (calcolo delle tasse, formattazione della data) si ripete nelle parti Android e iOS del progetto — questa è una violazione di DRY, anche se SRP è formalmente rispettato all'interno di ogni piattaforma. La soluzione è estrarre la logica comune in un modulo condiviso (KMM, C++).

Secondo il rapporto Google Android Architecture Guidelines (2023), i team che utilizzano moduli condivisi per la logica di business riducono il numero di bug quando i requisiti cambiano del 37% rispetto ai progetti che duplicano la logica tra piattaforme.

Perché la duplicazione del codice è pericolosa?

La duplicazione è la principale fonte di debito tecnico nei progetti mobili. Ogni copia di codice crea una dipendenza nascosta: per cambiare il comportamento, devi trovare e aggiornare tutte le copie. Perderne anche una significa un bug.

Considera uno scenario classico: in un'app Android, la formattazione della data viene eseguita in tre diverse Activity. Quando si passa a un nuovo formato (ad esempio, ISO 8601), lo sviluppatore corregge due file, dimentica il terzo — e l'utente vede le date nel vecchio formato. La valutazione dell'app cala e trovare il bug richiede il doppio del tempo.

Uno studio di Google Research (2020) ha mostrato che il 68% dei bug critici nelle applicazioni mobili è correlato a modifiche non sincronizzate in codice duplicato. Inoltre, correggere un tale bug in produzione costa 4,5 volte di più che se il codice fosse stato unificato dall'inizio.

Utilizza analizzatori statici (Detekt, SwiftLint) con regole che rilevano copy-paste. Configura CI in modo che le pull request con più di N righe di duplicazione non superino la revisione senza giustificazione.

DRY nello sviluppo mobile: esempi pratici

Duplicazione della logica UI in Android

Un anti-pattern tipico è copiare un adattatore RecyclerView con modifiche minori. Invece di un adattatore universale con configurazione, gli sviluppatori creano una classe separata per ogni schermata. Il refactoring estraendo una classe base comune riduce il codice del 30–50%.

kotlin
// Duplicazione: due adattatori separati
class UserAdapter {
    fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
    fun bind(item: Product) { /* ... */ }
}

// Refactoring DRY: classe base comune
abstract class BaseAdapter<T> {
    abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }

Nel primo esempio, ogni adattatore reimplementa il meccanismo bind da zero. Quando si aggiunge nuova logica (analytics, logging), ogni file dovrebbe essere modificato. Una classe base elimina questa duplicazione: la logica comune vive in un punto, la logica specifica nelle sottoclassi.

Duplicazione delle richieste di rete in iOS

Nei progetti iOS, la configurazione di URLSession — intestazioni, timeout, gestione degli errori — è spesso duplicata. Ogni servizio crea la propria sessione con impostazioni ripetute.

swift
// Duplicazione: ogni servizio configura la sessione da capo
class UserService {
    let session = URLSession(configuration: {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return cfg
    }())
}

// DRY: fabbrica di sessioni unificata
struct NetworkConfig {
    static var session: URLSession {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return URLSession(configuration: cfg)
    }
}

Estrarre la configurazione in un NetworkConfig unificato garantisce che tutti i servizi utilizzino le stesse intestazioni e timeout. Una modifica in un punto si applica automaticamente a tutte le richieste — ciò riduce il rischio di errori quando si cambiano chiavi API o versioni di protocollo.

Come applicare DRY in Android e iOS?

DRY attraverso ereditarietà e composizione

L'ereditarietà è un modo naturale per eliminare la duplicazione: la logica comune viene spostata in una classe base e la logica specifica nelle sottoclassi. Tuttavia, nello sviluppo mobile, l'abuso di ereditarietà crea gerarchie rigide difficili da mantenere. La composizione (iniezione di dipendenze) è un'alternativa più flessibile.

Un'analisi da Google I/O 2023: Modern Android Architecture ha mostrato che il 76% dei team Google preferisce la composizione all'ereditarietà per eliminare la duplicazione. Invece di un BaseViewModel con una dozzina di metodi, si consiglia di estrarre classi UseCase separate per ogni operazione di business e iniettarle dove necessario.

Scegli la composizione in tutti i casi tranne le relazioni “è-un.” Se la classe A è una specializzazione della classe B — l'ereditarietà è appropriata. Se A usa semplicemente la funzionalità di B — usa la composizione.

DRY attraverso classi di utilità

Le classi di utilità (Extensions, Helpers) sono il modo più semplice per evitare la duplicazione. Candidati tipici: formattazione delle date, validazione email, conversione di unità, lavoro con SharedPreferences/UserDefaults.

kotlin
// DRY: funzione unificata di formattazione data
fun Date.toDisplayFormat(): String {
    val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
    return sdf.format(this)
}

// Utilizzo ovunque nell'applicazione
textView.text = Date().toDisplayFormat()

L'estensione Date.toDisplayFormat() viene dichiarata una volta ed è disponibile in tutto il progetto. Se il formato deve cambiare da “dd.MM.yyyy” a “yyyy-MM-dd” — la correzione è in un file, non in ogni Activity o Fragment in cui avviene la formattazione. Questo è l'essenza di DRY.

DRY nella configurazione di Gradle (Android)

I progetti Android multi-modulo spesso duplicano le versioni delle dipendenze in ogni build.gradle. La soluzione è un catalogo delle versioni (libs.versions.toml) che centralizza tutte le versioni in un unico file.

Secondo la Documentazione per sviluppatori Android (2024), migrare a un catalogo delle versioni riduce i conflitti di dipendenza del 52% e accelera le build grazie a un unico punto di modifica.

Implementa un catalogo delle versioni all'avvio del progetto o durante la prima riorganizzazione dei moduli. Se il progetto contiene già duplicazione — dedica un giorno alla migrazione: si ripagherà al prossimo aggiornamento delle librerie.

Errori tipici nel seguire DRY

Astrazione prematura

L'astrazione prematura è l'errore più comune dei principianti. Uno sviluppatore vede due righe di codice simili e le estrae immediatamente in una funzione comune. Un mese dopo, i requisiti cambiano e la funzione comune si riempie di parametri e flag — più complessa della duplicazione originale. La Regola del Tre protegge esattamente da questo: non astrarre qualcosa che è apparso solo una o due volte.

Martin Fowler nel suo libro Refactoring (2019) raccomanda: “La duplicazione del codice non è sempre male. La duplicazione della conoscenza è male.” Se due righe coincidono casualmente ma esprimono concetti diversi — non è duplicazione, è coincidenza. La Regola del Tre aiuta a distinguere la coincidenza accidentale dalla duplicazione sistematica.

Prima di astrarre, valuta la semantica. Codice copiato con lo stesso significato — violazione di DRY. Codice con significato diverso ma sintassi simile — coincidenza che non richiede astrazione.

Parametrizzazione eccessiva

La parametrizzazione eccessiva si verifica quando una singola funzione tenta di coprire tutti gli scenari possibili attraverso flag e parametri booleani. Tale codice viola SRP e diventa illeggibile. Sintomo: se una funzione ha più di due parametri booleani — è un code smell di astrazione eccessiva.

Invece di una funzione con un flag useCache: Boolean, è meglio creare due funzioni separate con nomi chiari: fetchFromNetwork() e fetchFromCache(). La chiarezza è più importante di un'astrazione secca — questo riecheggia il principio KISS.

Refactoring della parametrizzazione eccessiva quando una funzione raggiunge 3+ parametri booleani. Dividi in funzioni separate con nomi chiari — ogni chiamata diventerà auto-documentante.

Domande frequenti

Cos'è DRY in parole semplici?

DRY (Don't Repeat Yourself) è un principio che richiede di memorizzare ogni unità logica in un unico posto. Se lo stesso codice appare in più parti di un progetto — è una violazione di DRY. Soluzione: estrai la logica ripetitiva in una funzione, classe o modulo separato.

In cosa differisce DRY da WET?

WET (Write Everything Twice) è l'opposto di DRY, dove la duplicazione è considerata accettabile. Nei progetti WET, lo stesso frammento di codice può esistere in cinque copie e quando i requisiti cambiano, lo sviluppatore corregge ogni copia separatamente. WET aumenta il rischio di bug e rallenta lo sviluppo.

Quando DRY può essere dannoso?

DRY è dannoso quando porta a un'astrazione prematura: quando due sezioni di codice simili ma semanticamente diverse vengono forzatamente unite in una funzione. Ciò genera codice complesso e sovraccarico di parametri. La Regola del Tre aiuta a evitare questo errore: astrai solo dopo la terza ripetizione.

Come applicare DRY nei progetti Android?

In Android, DRY si applica tramite cataloghi delle versioni (libs.versions.toml), classi base comuni per adattatori, fabbriche ViewModel ed estensioni Kotlin di utilità. Si consiglia di estrarre la logica di business in moduli condivisi (KMM) e utilizzare View Binding per eliminare la duplicazione di findViewById.

Come applicare DRY nei progetti iOS?

In iOS, DRY si ottiene tramite protocolli con implementazione predefinita, configurazioni di rete condivise (NetworkConfig), fabbriche di celle UICollectionView e pacchetti SPM con logica di business comune. Le estensioni dei tipi standard (Date, String, URL) riducono la duplicazione nella formattazione e nella validazione.

Riepilogo

  • DRY (Don't Repeat Yourself) è il principio di memorizzare ogni elemento di conoscenza una volta in un sistema, formulato nel libro “The Pragmatic Programmer.”
  • La duplicazione del codice è la principale fonte di debito tecnico, aumentando il costo delle modifiche e il rischio di bug.
  • Copy-paste senza refactoring porta a copie divergenti e modifiche non sincronizzate quando i requisiti vengono modificati.
  • La Regola del Tre è una linea guida pratica: astrai il codice solo dopo che è apparso in tre punti.
  • La composizione è preferibile all'ereditarietà per eliminare la duplicazione nei progetti mobili.
  • I cataloghi delle versioni (libs.versions.toml) centralizzano la gestione delle dipendenze in Android e riducono i conflitti del 52%.
  • L'astrazione prematura è più dannosa della duplicazione — non astrarre coincidenze sintattiche casuali; distinguile dalla duplicazione sistematica della conoscenza.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche