DRY în dezvoltarea mobilă — ce este, principiul și de ce duplicarea dăunează

Autor: IT Sectr Publicat: 2026-05-12 Timp de citire: 8 min

DRY (Don't Repeat Yourself) — un principiu fundamental al dezvoltării formulat de Andy Hunt și Dave Thomas în cartea „The Pragmatic Programmer”. Acesta spune: fiecare parte a cunoașterii dintr-un sistem trebuie să aibă o reprezentare unică, fără ambiguitate, autoritară. Conform The Pragmatic Programmer, 20th Anniversary Edition, încălcarea DRY duce la situația în care modificarea unui element necesită corecții în zeci de locuri, iar fiecare fragment omis devine o sursă de eroare.

Principalele puncte

  • DRY — principiul stocării unice a fiecărei cunoașteri în sistem, eliminând duplicarea codului și a datelor.
  • Duplicarea crește costul întreținerii: o modificare într-un loc necesită corecții sincrone în toate copiile.
  • Copy-paste — principalul dușman al DRY: codul copiat diverge rapid, iar dezvoltatorul uită unde mai trebuie făcute corecții.
  • Abstractizarea — instrumentul principal al DRY: extragerea fragmentelor repetitive în funcții, clase sau module.
  • Rule of Three — regula practică: dacă codul se repetă în trei locuri, a sosit timpul pentru abstractizare.

Ce este DRY?

DRY (Don't Repeat Yourself) — un principiu de dezvoltare care cere stocarea unică a fiecărui element de cunoaștere în proiect. Aceasta înseamnă că orice logică, configurație sau metadate trebuie să existe exact într-un singur loc.

Termenul a fost introdus de Andy Hunt și Dave Thomas în 1999 în cartea „The Pragmatic Programmer”. Autorii au definit DRY ca „fiecare parte a cunoașterii trebuie să aibă o reprezentare unică, coerentă în sistem”. Opusul DRY — abordarea WET (Write Everything Twice), unde duplicarea este considerată normă.

Conform cercetării University of California, Davis (2019), proiectele cu un nivel ridicat de duplicare a codului petrec cu 42% mai mult timp pentru remedierea erorilor. Motivul este că dezvoltatorul trebuie să găsească și să modifice toate copiile aceluiași fragment — iar la căutarea manuală, omisiunile sunt inevitabile.

Aplică DRY ca criteriu al calității codului. Dacă observi că același model apare în proiect de trei ori — extrage-l într-o abstractizare, fără a aștepta a patra repetare.

Diferența dintre DRY și principiul responsabilității unice

Single Responsibility Principle (SRP) din SOLID afirmă că o clasă trebuie să aibă un singur motiv pentru a fi modificată. DRY este mai larg: acoperă nu doar clasele, ci și datele, configurația, documentația și chiar regulile de afaceri. SRP este despre limitele responsabilității, DRY — despre inadmisibilitatea copierii.

În dezvoltarea mobilă, această diferență este deosebit de vizibilă. Dacă aceeași regulă de afaceri (calculul taxei, formatarea datei) se repetă în părțile Android și iOS — este o încălcare a DRY, deși SRP este respectat formal în cadrul fiecărei platforme. Soluția — extragerea logicii comune într-un modul partajat (KMM, C++).

Conform raportului Google Android Architecture Guidelines (2023), echipele care folosesc module comune pentru logica de afaceri reduc numărul de erori la modificarea cerințelor cu 37% comparativ cu proiectele cu duplicarea logicii între platforme.

De ce este periculoasă duplicarea codului?

Duplicarea — principala sursă a datoriei tehnice în proiectele mobile. Fiecare copie a codului creează o dependență ascunsă: pentru a modifica comportamentul, trebuie găsite și actualizate toate copiile. Omiterea chiar și a uneia înseamnă o eroare.

Să considerăm o situație clasică: într-o aplicație Android, formatarea datei este realizată în trei Activity-uri diferite. La trecerea la un format nou (de exemplu, ISO 8601), dezvoltatorul corectează două fișiere, uită de al treilea — iar utilizatorul vede data în format vechi. Evaluarea utilizatorilor aplicației scade, iar găsirea erorii durează de două ori mai mult.

Cercetarea Google Research (2020) a arătat: 68% dintre erorile critice în aplicațiile mobile sunt legate de modificarea nesincronizată a codului duplicat. Costul remedierii unei astfel de erori în production este de 4,5 ori mai mare decât dacă codul ar fi fost unitar de la început.

Folosește un analizor static (Detekt, SwiftLint) cu reguli care interzic detectarea copy-paste. Configurează CI astfel încât pull-request-urile cu duplicare de peste N linii să nu treacă de review fără justificare.

DRY în dezvoltarea mobilă: exemple practice

Duplicarea logicii UI în Android

Un anti-pattern tipic — copierea adaptorului RecyclerView cu modificări minore. În loc de un adaptor universal cu configurație, dezvoltatorii creează o clasă separată pentru fiecare ecran. Refactorizarea cu extragerea unei clase de bază comune scurtează codul cu 30–50%.

kotlin
// Duplicare: doi adaptori separați
class UserAdapter {
    fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
    fun bind(item: Product) { /* ... */ }
}

// Refactorizare DRY: clasă de bază comună
abstract class BaseAdapter<T> {
    abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }

În primul exemplu, fiecare adaptor implementează din nou mecanismul bind. La adăugarea unei noi logici (analitică, logare) ar trebui modificate toate fișierele. Clasa de bază elimină această duplicare: logica comună trăiește într-un singur loc, iar cea specifică — în clasele derivate.

Duplicarea cererilor de rețea în iOS

În proiectele iOS se duplică adesea configurația URLSession — antete, timeout-uri, gestionarea erorilor. Fiecare serviciu își creează propria sesiune cu setări repetitive.

swift
// Duplicare: fiecare serviciu configurează sesiunea de la zero
class UserService {
    let session = URLSession(configuration: {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return cfg
    }())
}

// DRY: fabrică unică de sesiuni
struct NetworkConfig {
    static var session: URLSession {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return URLSession(configuration: cfg)
    }
}

Extragerea configurației într-un NetworkConfig unitar garantează că toate serviciile folosesc aceleași antete și timeout-uri. Modificarea într-un singur loc se aplică automat tuturor cererilor — aceasta reduce riscul de erori la schimbarea cheii API sau a versiunii protocolului.

Cum se aplică DRY în Android și iOS?

DRY prin moștenire și compoziție

Moștenirea — modul natural de eliminare a duplicării: logica comună este extrasă într-o clasă de bază, iar cea specifică — în clasele derivate. Totuși, în dezvoltarea mobilă, abuzul de moștenire creează ierarhii rigide care sunt greu de întreținut. Compoziția (injecția dependențelor) — o alternativă mai flexibilă.

Analiza Google I/O 2023: Modern Android Architecture a arătat că 76% dintre echipele Google preferă compoziția în locul moștenirii pentru eliminarea duplicării. În loc de BaseViewModel cu zece metode, se recomandă extragerea unor clase UseCase separate pentru fiecare operațiune de afaceri și injectarea lor acolo unde sunt necesare.

Alege compoziția în toate cazurile, cu excepția relațiilor „este-un”. Dacă clasa A este o specializare a clasei B — moștenirea este potrivită. Dacă A doar folosește funcționalitatea lui B — folosește compoziția.

DRY prin clase utilitare

Clasele utilitare (Extensions, Helpers) — cel mai simplu mod de a evita duplicarea. Candidați tipici: formatarea datelor, validarea email-urilor, conversia unităților, lucrul cu SharedPreferences/UserDefaults.

kotlin
// DRY: funcție unică de formatare a datei
fun Date.toDisplayFormat(): String {
    val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
    return sdf.format(this)
}

// Utilizare în orice parte a aplicației
textView.text = Date().toDisplayFormat()

Extensia Date.toDisplayFormat() este declarată o dată și accesibilă în întregul proiect. Dacă trebuie schimbat formatul din „dd.MM.yyyy” în „yyyy-MM-dd” — corecția se face într-un singur fișier, nu în fiecare Activity sau Fragment unde apare formatarea. Aceasta este esența DRY.

DRY în configurația Gradle (Android)

Proiectele Android multi-modul duplică adesea versiunile dependențelor în fiecare build.gradle. Soluția — version catalog (libs.versions.toml), care centralizează toate versiunile într-un singur fișier.

Conform Android Developer Documentation (2024), migrarea la version catalog reduce conflictele de dependențe cu 52% și accelerează construcția datorită unui punct unic de corecții.

Implementează version catalog la începutul proiectului sau la prima reorganizare a modulelor. Dacă proiectul are deja duplicare — alocă o zi pentru migrare: se va amortiza la următoarea actualizare a bibliotecilor.

Greșeli tipice în respectarea DRY

Abstractizarea prematură

Abstractizarea prematură — cea mai frecventă greșeală a începătorilor. Dezvoltatorul vede două linii de cod similare și le extrage imediat într-o funcție comună. După o lună, cerințele se schimbă, iar funcția comună se umple de parametri și flag-uri — devine mai complexă decât duplicarea inițială. Rule of Three protejează tocmai de aceasta: nu abstractiza ceea ce a apărut o-dată sau de două ori.

Martin Fowler în cartea Refactoring (2019) recomandă: „Duplicarea codului nu este întotdeauna rea. Duplicarea cunoașterii este rea”. Dacă două linii coincid întâmplător, dar exprimă concepte diferite — nu este duplicare, ci coincidență. Rule of Three ajută să deosebim coincidența întâmplătoare de duplicarea sistematică.

Înainte de a abstractiza, evaluează semantica. Codul copiat cu același sens — încălcare a DRY. Codul cu sens diferit, dar sintaxă similară — coincidență care nu necesită abstractizare.

Parametrizarea excesivă

Parametrizarea excesivă apare atunci când o singură funcție încearcă să acopere toate scenariile posibile prin flag-uri și parametri booleeni. Un astfel de cod încalcă SRP și devine ilizibil. Simptom: dacă funcția are mai mult de doi parametri booleeni — acesta este un miros de cod (code smell) al abstractizării excesive.

În loc de o funcție cu flag-ul useCache: Boolean, este mai bine să creezi două funcții separate cu nume clare: fetchFromNetwork() și fetchFromCache(). Explicitarea este mai importantă decât abstractizarea uscată — aceasta se corelează cu principiul KISS.

Refactorizează parametrizarea excesivă atunci când funcția atinge 3+ parametri booleeni. Împarte în funcții separate cu nume clare — fiecare apel va deveni auto-documentat.

Întrebări frecvente

Ce este DRY în cuvinte simple?

DRY (Don't Repeat Yourself) — principiul care cere stocarea fiecărei unități logice într-un singur loc. Dacă același cod apare în mai multe părți ale proiectului — este o încălcare a DRY. Remedierea: extrage logica repetată într-o funcție, clasă sau modul separat.

Cu ce se deosebește DRY de WET?

WET (Write Everything Twice) — antiteza DRY, în care duplicarea este considerată acceptabilă. În proiectele WET, același fragment de cod poate exista în cinci copii, iar la schimbarea cerințelor, dezvoltatorul corectează fiecare copie separat. WET crește riscul de erori și încetinește dezvoltarea.

Când poate dăuna DRY?

DRY dăunează la abstractizarea prematură: când două fragmente de cod similare, dar semantic diferite, sunt combinate forțat într-o singură funcție. Aceasta generează cod complex, supraîncărcat cu parametri. Rule of Three ajută la evitarea acestei greșeli: abstractizează doar după a treia repetare.

Cum se aplică DRY în proiectele Android?

În Android, DRY se aplică prin version catalog (libs.versions.toml), clase de bază comune pentru adaptoare, fabrici ViewModel și extensii utilitare Kotlin. Se recomandă extragerea logicii de afaceri în module partajate (KMM) și utilizarea View Binding pentru eliminarea duplicării findViewById.

Cum se aplică DRY în proiectele iOS?

În iOS, DRY se atinge prin protocoale cu implementare implicită, configurații de rețea comune (NetworkConfig), fabrici de celule UICollectionView și pachete SPM cu logică de afaceri comună. Extensions ale tipurilor standard (Date, String, URL) reduc duplicarea formatării și validării.

Rezumat

  • DRY (Don't Repeat Yourself) — principiul stocării unice a fiecărei cunoașteri în sistem, formulat în cartea „The Pragmatic Programmer”.
  • Duplicarea codului — principala sursă a datoriei tehnice, care crește costul modificărilor și riscul de erori.
  • Copy-paste fără refactorizare duce la divergența copiilor și corecții nesincronizate la schimbarea cerințelor.
  • Rule of Three — regula practică: abstractizează codul doar după ce a apărut în trei locuri.
  • Compoziția este preferată moștenirii pentru eliminarea duplicării în proiectele mobile.
  • Version catalog (libs.versions.toml) centralizează gestionarea dependențelor în Android și reduce conflictele cu 52%.
  • Abstractizarea prematură este mai dăunătoare decât duplicarea — nu abstractiza coincidențele sintactice întâmplătoare, deosebește-le de duplicarea sistematică a cunoașterii.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și