DRY (Don't Repeat Yourself) — isang pangunahing prinsipyo ng development na binuo nina Andy Hunt at Dave Thomas sa aklat na “The Pragmatic Programmer”. Ito ay nagsasaad: bawat bahagi ng kaalaman sa isang sistema ay dapat magkaroon ng nag-iisa, hindi malabo, at awtoritatibong representasyon. Ayon sa The Pragmatic Programmer, 20th Anniversary Edition, ang paglabag sa DRY ay nagdudulot na ang pagbabago ng isang elemento ay nangangailangan ng mga pagwawasto sa dose-dosenang lugar, at bawat napalampas na fragment ay nagiging mapagkukunan ng bug.
Mga Pangunahing Punto
DRY (Don't Repeat Yourself) — isang prinsipyo ng development na nangangailangan ng isang beses na pag-iimbak ng bawat elemento ng kaalaman sa proyekto. Nangangahulugan ito na ang bawat lohika, konpigurasyon o metadata ay dapat na umiiral nang eksakto sa isang lugar.
Ang termino ay ipinakilala nina Andy Hunt at Dave Thomas noong 1999 sa aklat na “The Pragmatic Programmer”. Tinukoy ng mga may-akda ang DRY bilang “bawat bahagi ng kaalaman ay dapat magkaroon ng nag-iisa, pare-parehong representasyon sa sistema”. Ang kabaligtaran ng DRY — ang pamamaraang WET (Write Everything Twice), kung saan ang pag-uulit ay itinuturing na pamantayan.
Ayon sa pananaliksik ng University of California, Davis (2019), ang mga proyektong may mataas na antas ng pag-uulit ng code ay gumugugol ng 42% mas maraming oras sa pag-aayos ng mga bug. Ang dahilan ay kailangang hanapin at baguhin ng developer ang lahat ng kopya ng parehong fragment — at sa manu-manong paghahanap, ang mga pagkakamali ay hindi maiiwasan.
Ilapat ang DRY bilang pamantayan ng kalidad ng code. Kung napapansin mo na ang parehong pattern ay lumilitaw sa proyekto nang tatlong beses — ihiwalay ito sa isang abstraksyon, nang hindi naghihintay ng ikaapat na pag-uulit.
Single Responsibility Principle (SRP) mula sa SOLID ay nagsasaad na ang isang klase ay dapat magkaroon ng isang dahilan para magbago. Ang DRY ay mas malawak: hindi lamang mga klase, kundi pati na rin ang data, konpigurasyon, dokumentasyon, at maging ang mga panuntunan sa negosyo. Ang SRP ay tungkol sa mga hangganan ng responsibilidad, ang DRY — tungkol sa hindi pagtanggap ng pagkopya.
Sa mobile development, ang pagkakaibang ito ay lalong kapansin-pansin. Kung ang parehong panuntunan sa negosyo (pagkalkula ng buwis, pag-format ng petsa) ay nauulit sa mga bahagi ng Android at iOS — ito ay paglabag sa DRY, kahit na ang SRP ay pormal na sinusunod sa loob ng bawat platform. Solusyon — ihiwalay ang karaniwang lohika sa isang shared module (KMM, C++).
Ayon sa ulat ng Google Android Architecture Guidelines (2023), ang mga team na gumagamit ng mga shared module para sa lohika ng negosyo ay nagbabawas ng bilang ng mga bug kapag nagbago ang mga kinakailangan ng 37% kumpara sa mga proyektong may pag-uulit ng lohika sa pagitan ng mga platform.
Pag-uulit — pangunahing mapagkukunan ng teknikal na utang sa mga mobile na proyekto. Bawat kopya ng code ay lumilikha ng nakatagong dependency: upang baguhin ang pag-uugali, kailangang hanapin at i-update ang lahat ng kopya. Ang makaligtaan kahit isa ay nangangahulugan ng bug.
Isaalang-alang ang isang klasikong sitwasyon: sa isang Android app, ang pag-format ng petsa ay ginagawa sa tatlong magkakaibang Activity. Kapag lumipat sa bagong format (hal. ISO 8601), itinatama ng developer ang dalawang file, nakakalimutan ang pangatlo — at nakikita ng user ang petsa sa lumang format. Ang rating ng user ng app ay bumababa, at ang paghahanap ng bug ay tumatagal ng dalawang beses na mas mahaba.
Ang pananaliksik ng Google Research (2020) ay nagpakita: 68% ng mga kritikal na bug sa mga mobile app ay nauugnay sa hindi sabay-sabay na pagbabago ng inuulit na code. Ang gastos sa pag-aayos ng naturang bug sa production ay 4.5 beses na mas mataas kaysa kung ang code ay magkakatulad mula sa simula.
Gumamit ng static analyzer (Detekt, SwiftLint) na may mga panuntunang nagbabawal sa detection ng copy-paste. I-configure ang CI upang ang mga pull-request na may pag-uulit na higit sa N linya ay hindi dumaan sa review nang walang katwiran.
Isang tipikal na anti-pattern — pagkopya ng RecyclerView adapter na may maliliit na pagbabago. Sa halip na isang unibersal na adapter na may konpigurasyon, ang mga developer ay gumagawa ng hiwalay na klase para sa bawat screen. Ang refactoring na may paghihiwalay ng isang karaniwang base class ay nagpapaikli ng code ng 30–50%.
// Pag-uulit: dalawang magkahiwalay na adapter
class UserAdapter {
fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
fun bind(item: Product) { /* ... */ }
}
// DRY-refactoring: karaniwang base class
abstract class BaseAdapter<T> {
abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }
Sa unang halimbawa, bawat adapter ay muling nag-implementa ng bind mechanism. Kapag nagdadagdag ng bagong lohika (analytics, logging), kailangang baguhin ang bawat file. Ang base class ay nag-aalis ng pag-uulit na ito: ang karaniwang lohika ay nabubuhay sa isang lugar, ang tiyak na lohika sa mga derived class.
Sa iOS na mga proyekto, madalas na inuulit ang konpigurasyon ng URLSession — mga header, timeout, paghawak ng error. Bawat serbisyo ay gumagawa ng sarili nitong session na may paulit-ulit na mga setting.
// Pag-uulit: bawat serbisyo ay nagko-configure ng session mula sa simula
class UserService {
let session = URLSession(configuration: {
let cfg = URLSessionConfiguration.default
cfg.timeoutIntervalForRequest = 30
cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
return cfg
}())
}
// DRY: nagkakaisang factory ng session
struct NetworkConfig {
static var session: URLSession {
let cfg = URLSessionConfiguration.default
cfg.timeoutIntervalForRequest = 30
cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
return URLSession(configuration: cfg)
}
}
Ang paghihiwalay ng konpigurasyon sa isang nagkakaisang NetworkConfig ay ginagarantiyahan na lahat ng serbisyo ay gumagamit ng parehong mga header at timeout. Ang pagbabago sa isang lugar ay awtomatikong naa-apply sa lahat ng request — binabawasan nito ang panganib ng mga error kapag nagbago ang API key o bersyon ng protocol.
Mana — natural na paraan ng pag-aalis ng pag-uulit: ang karaniwang lohika ay inihihiwalay sa isang base class, at ang tiyak na lohika sa mga derived class. Gayunpaman, sa mobile development, ang pag-abuso sa mana ay lumilikha ng matigas na hierarchy na mahirap panatilihin. Komposisyon (dependency injection) — isang mas nababagong alternatibo.
Ang pagsusuri ng Google I/O 2023: Modern Android Architecture ay nagpakita na 76% ng mga team ng Google ay mas pinipili ang komposisyon kaysa mana para sa pag-aalis ng pag-uulit. Sa halip na BaseViewModel na may sampung pamamaraan, inirerekomenda ang paghihiwalay ng mga hiwalay na UseCase class para sa bawat operasyon ng negosyo at pag-inject ng mga ito kung saan kinakailangan.
Piliin ang komposisyon sa lahat ng kaso maliban sa “is-a” na relasyon. Kung ang Class A ay isang espesyalisasyon ng Class B — ang mana ay angkop. Kung A ay gumagamit lamang ng functionality ng B — gamitin ang komposisyon.
Utility class (Extensions, Helpers) — pinakasimpleng paraan upang maiwasan ang pag-uulit. Karaniwang mga kandidato: pag-format ng petsa, pag-validate ng email, conversion ng unit, paggawa sa SharedPreferences/UserDefaults.
// DRY: nagkakaisang function sa pag-format ng petsa
fun Date.toDisplayFormat(): String {
val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
return sdf.format(this)
}
// Paggamit sa kahit saang bahagi ng aplikasyon
textView.text = Date().toDisplayFormat()
Ang extension na Date.toDisplayFormat() ay idineklara nang isang beses at magagamit sa buong proyekto. Kung kailangang baguhin ang format mula “dd.MM.yyyy” patungong “yyyy-MM-dd” — pagwawasto sa isang file, hindi sa bawat Activity o Fragment kung saan lumilitaw ang pag-format. Ito ang eksaktong kakanyahan ng DRY.
Ang mga multi-module na Android project ay madalas na inuulit ang mga bersyon ng dependency sa bawat build.gradle. Solusyon — version catalog (libs.versions.toml), na nagse-centralize ng lahat ng bersyon sa isang file.
Ayon sa Android Developer Documentation (2024), ang migrasyon sa version catalog ay nagbabawas ng mga conflict ng dependency ng 52% at nagpapabilis ng build dahil sa iisang punto ng pagwawasto.
Ipatupad ang version catalog sa simula ng proyekto o sa unang reorganisasyon ng mga modyul. Kung ang proyekto ay mayroon nang pag-uulit — maglaan ng isang araw para sa migrasyon: ito ay magbabayad sa susunod na pag-update ng mga library.
Maagang abstraksyon — pinakakaraniwang pagkakamali ng mga baguhan. Nakikita ng developer ang dalawang magkatulad na linya ng code at agad na inihihiwalay ang mga ito sa isang karaniwang function. Pagkatapos ng isang buwan, nagbabago ang mga kinakailangan at ang karaniwang function ay napupuno ng mga parameter at flag — nagiging mas kumplikado kaysa sa orihinal na pag-uulit. Ang Rule of Three ay nagpoprotekta laban dito: huwag abstraksyon kung ano ang lumitaw nang isa o dalawang beses.
Si Martin Fowler sa aklat na Refactoring (2019) ay nagrerekomenda: “Ang pag-uulit ng code ay hindi palaging masama. Ang pag-uulit ng kaalaman ay masama”. Kung ang dalawang linya ay nagkataong magkatugma ngunit nagpapahayag ng magkaibang konsepto — ito ay hindi pag-uulit, kundi pagkakataon. Ang Rule of Three ay tumutulong na makilala ang nagkataong pagkakatugma mula sa sistematikong pag-uulit.
Bago mag-abstrak, suriin ang semantika. Ang kinopyang code na may parehong kahulugan — paglabag sa DRY. Ang code na may magkaibang kahulugan ngunit katulad na syntax — pagkakataon na hindi nangangailangan ng abstraksyon.
Labis na parametrisasyon ay lumilitaw kapag ang isang function ay sumusubok na saklawin ang lahat ng posibleng senaryo sa pamamagitan ng mga flag at boolean na parameter. Ang naturang code ay lumalabag sa SRP at nagiging hindi nababasa. Sintoma: kung ang isang function ay may higit sa dalawang boolean na parameter — ito ay isang code smell ng labis na abstraksyon.
Sa halip na isang function na may flag na useCache: Boolean, mas mainam na gumawa ng dalawang hiwalay na function na may malinaw na pangalan: fetchFromNetwork() at fetchFromCache(). Ang pagiging malinaw ay mas mahalaga kaysa tuyong abstraksyon — ito ay kaugnay sa prinsipyong KISS.
I-refactor ang labis na parametrisasyon kapag ang function ay umabot sa 3+ boolean na parameter. Hatiin sa hiwalay na mga function na may malinaw na pangalan — bawat tawag ay magiging self-documenting.
Mga Madalas Itanong
DRY (Don't Repeat Yourself) — prinsipyo na nangangailangan ng pag-iimbak ng bawat lohikal na yunit sa isang lugar. Kung ang parehong code ay lumilitaw sa maraming bahagi ng proyekto — ito ay paglabag sa DRY. Pagwawasto: ilipat ang inuulit na lohika sa isang hiwalay na function, klase o modyul.
WET (Write Everything Twice) — kabaligtaran ng DRY, kung saan ang pag-uulit ay itinuturing na katanggap-tanggap. Sa WET na mga proyekto, ang parehong fragment ng code ay maaaring umiral sa limang kopya, at kapag nagbago ang mga kinakailangan, itatama ng developer ang bawat kopya nang hiwalay. Ang WET ay nagpapataas ng panganib ng mga bug at nagpapabagal ng development.
Ang DRY ay nakakasama sa maagang abstraksyon: kapag ang dalawang magkatulad ngunit semantikong magkaibang bahagi ng code ay pinagsama-sama sa isang function. Lumilikha ito ng kumplikado, overloaded na code na may mga parameter. Ang Rule of Three ay tumutulong na maiwasan ang pagkakamaling ito: mag-abstrak lamang pagkatapos ng ikatlong pag-uulit.
Sa Android, ang DRY ay inilalapat sa pamamagitan ng version catalog (libs.versions.toml), mga karaniwang base class para sa mga adapter, ViewModel factory at mga kapaki-pakinabang na Kotlin extension. Inirerekomenda na ihiwalay ang lohika ng negosyo sa mga shared module (KMM) at gamitin ang View Binding para alisin ang pag-uulit ng findViewById.
Sa iOS, ang DRY ay nakakamit sa pamamagitan ng mga protocol na may default na implementasyon, mga shared network configuration (NetworkConfig), UICollectionView cell factory at SPM package na may shared business logic. Ang Extensions ng mga standard na uri (Date, String, URL) ay nagbabawas ng pag-uulit ng pag-format at pag-validate.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din