DRY (Don't Repeat Yourself) — en fundamental utvecklingsprincip formulerad av Andy Hunt och Dave Thomas i boken “The Pragmatic Programmer”. Den säger: varje kunskapsdel i ett system måste ha en unik, entydig, auktoritativ representation. Enligt The Pragmatic Programmer, 20th Anniversary Edition leder brott mot DRY till att ändring av ett element kräver korrigeringar på dussintals platser och varje missat fragment blir en källa till buggar.
Huvudpunkter
DRY (Don't Repeat Yourself) — en utvecklingsprincip som kräver engångslagring av varje kunskapselement i projektet. Det innebär att varje logik, konfiguration eller metadata måste finnas på exakt en plats.
Termen introducerades av Andy Hunt och Dave Thomas 1999 i boken “The Pragmatic Programmer”. Författarna definierade DRY som “varje kunskapsdel måste ha en unik, konsekvent representation i systemet”. Motsatsen till DRY — WET-metoden (Write Everything Twice), där duplicering anses vara norm.
Enligt forskning från University of California, Davis (2019) lägger projekt med hög kodduplicering 42% mer tid på att åtgärda buggar. Anledningen är att utvecklaren måste hitta och ändra alla kopior av samma fragment — och vid manuell sökning är förbiseenden oundvikliga.
Tillämpa DRY som ett kvalitetskriterium för kod. Om du märker att samma mönster förekommer tre gånger i projektet — extrahera det till en abstraktion, utan att vänta på den fjärde upprepningen.
Single Responsibility Principle (SRP) från SOLID säger att en klass ska ha en anledning att ändras. DRY är bredare: det omfattar inte bara klasser utan även data, konfiguration, dokumentation och till och med affärsregler. SRP handlar om ansvarsgränser, DRY — om att kopiering är oacceptabelt.
Inom mobilutveckling är denna skillnad särskilt märkbar. Om samma affärsregel (skatteberäkning, datumformatering) upprepas i Android- och iOS-delarna — är det ett brott mot DRY, även om SRP formellt efterlevs inom varje plattform. Lösning — extrahera gemensam logik till en delad modul (KMM, C++).
Enligt rapporten Google Android Architecture Guidelines (2023) minskar team som använder delade moduler för affärslogik antalet buggar vid ändring av krav med 37% jämfört med projekt med logikduplicering mellan plattformar.
Duplicering — den främsta källan till tekniskt skuld i mobilprojekt. Varje kopia av kod skapar ett dolt beroende: för att ändra beteendet måste alla kopior hittas och uppdateras. Att missa ens en enda innebär en bugg.
Betrakta en klassisk situation: i en Android-app utförs datumformatering i tre olika Activity. Vid övergång till ett nytt format (t.ex. ISO 8601) korrigerar utvecklaren två filer, glömmer den tredje — och användaren ser datumet i gammalt format. Användarbetyget för appen sjunker och att hitta buggen tar dubbelt så lång tid.
Forskning från Google Research (2020) visade: 68% av kritiska buggar i mobilappar är relaterade till osynkron ändring av duplicerad kod. Kostnaden för att åtgärda en sådan bugg i produktion är 4,5 gånger högre än om koden hade varit enhetlig från början.
Använd en statisk analysator (Detekt, SwiftLint) med regler som förbjuder detektering av copy-paste. Konfigurera CI så att pull-requests med duplicering över N rader inte passerar review utan motivering.
Ett typiskt anti-mönster — kopiering av RecyclerView-adapter med mindre ändringar. I stället för en universell adapter med konfiguration skapar utvecklare en separat klass för varje skärm. Refaktorering med extrahering av en gemensam basklass förkortar koden med 30–50%.
// Duplicering: två separata adaptrar
class UserAdapter {
fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
fun bind(item: Product) { /* ... */ }
}
// DRY-refaktorering: gemensam basklass
abstract class BaseAdapter<T> {
abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }
I det första exemplet implementerar varje adapter bind-mekanismen på nytt. Vid tillägg av ny logik (analys, loggning) skulle varje fil behöva ändras. Basklassen eliminerar denna duplicering: gemensam logik lever på en plats, specifik logik i de härledda klasserna.
I iOS-projekt dupliceras ofta URLSession-konfigurationen — rubriker, tidsgränser, felhantering. Varje tjänst skapar sin egen session med repeterande inställningar.
// Duplicering: varje tjänst konfigurerar sessionen på nytt
class UserService {
let session = URLSession(configuration: {
let cfg = URLSessionConfiguration.default
cfg.timeoutIntervalForRequest = 30
cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
return cfg
}())
}
// DRY: enhetlig sessionfabrik
struct NetworkConfig {
static var session: URLSession {
let cfg = URLSessionConfiguration.default
cfg.timeoutIntervalForRequest = 30
cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
return URLSession(configuration: cfg)
}
}
Att extrahera konfigurationen till en enhetlig NetworkConfig garanterar att alla tjänster använder samma rubriker och tidsgränser. En ändring på en plats tillämpas automatiskt på alla förfrågningar — detta minskar risken för fel vid ändring av API-nyckel eller protokollversion.
Arv — ett naturligt sätt att eliminera duplicering: gemensam logik extraheras till en basklass och specifik logik till härledda klasser. Inom mobilutveckling skapar missbruk av arv dock stela hierarkier som är svåra att underhålla. Komposition (beroendeinjektion) — ett mer flexibelt alternativ.
Analys av Google I/O 2023: Modern Android Architecture visade att 76% av Google-teamen föredrar komposition framför arv för att eliminera duplicering. I stället för BaseViewModel med tio metoder rekommenderas att extrahera separata UseCase-klasser för varje affärsoperation och injicera dem där de behövs.
Välj komposition i alla fall utom “är-en”-relationer. Om klass A är en specialisering av klass B — är arv lämpligt. Om A bara använder B:s funktionalitet — använd komposition.
Verktygsklasser (Extensions, Helpers) — det enklaste sättet att undvika duplicering. Typiska kandidater: datumformatering, e-postvalidering, enhetskonvertering, arbete med SharedPreferences/UserDefaults.
// DRY: enhetlig datumformateringsfunktion
fun Date.toDisplayFormat(): String {
val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
return sdf.format(this)
}
// Användning var som helst i applikationen
textView.text = Date().toDisplayFormat()
Tillägget Date.toDisplayFormat() deklareras en gång och är tillgängligt i hela projektet. Om formatet behöver ändras från “dd.MM.yyyy” till “yyyy-MM-dd” — korrigering i en fil, inte i varje Activity eller Fragment där formatering förekommer. Detta är kärnan i DRY.
Modulbaserade Android-projekt duplicerar ofta beroendeversioner i varje build.gradle. Lösning — version catalog (libs.versions.toml), som centraliserar alla versioner i en fil.
Enligt Android Developer Documentation (2024) minskar migrering till version catalog beroendekonflikter med 52% och snabbar upp byggandet tack vare en enda korrigeringspunkt.
Inför version catalog i början av projektet eller vid den första omorganisationen av moduler. Om projektet redan har duplicering — avsätt en dag för migrering: det kommer att löna sig vid nästa biblioteksuppdatering.
Förtida abstraktion — det vanligaste misstaget bland nybörjare. Utvecklaren ser två liknande kodrader och extraherar dem omedelbart till en gemensam funktion. Efter en månad ändras kraven och den gemensamma funktionen fylls med parametrar och flaggor — blir mer komplex än den ursprungliga dupliceringen. Rule of Three skyddar just mot detta: abstrahera inte det som förekommit en eller två gånger.
Martin Fowler rekommenderar i boken Refactoring (2019): “Kodduplicering är inte alltid dåligt. Kunskapsduplicering är dåligt”. Om två rader råkar sammanfalla men uttrycker olika koncept — är det inte duplicering, utan slump. Rule of Three hjälper att skilja slumpmässig sammanfall från systematisk duplicering.
Innan du abstraherar, utvärdera semantiken. Kopierad kod med samma betydelse — brott mot DRY. Kod med olika betydelse men liknande syntax — slump som inte kräver abstraktion.
Överdriven parametrisering uppstår när en funktion försöker täcka alla möjliga scenarier genom flaggor och booleska parametrar. Sådan kod bryter mot SRP och blir oläslig. Symptom: om en funktion har fler än två booleska parametrar — är detta en kodlukt (code smell) av överdriven abstraktion.
I stället för en funktion med flaggan useCache: Boolean är det bättre att skapa två separata funktioner med tydliga namn: fetchFromNetwork() och fetchFromCache(). Tydlighet är viktigare än torr abstraktion — detta överensstämmer med KISS-principen.
Refaktorera överdriven parametrisering när funktionen når 3+ booleska parametrar. Dela upp i separata funktioner med tydliga namn — varje anrop blir självdokumenterande.
Vanliga frågor
DRY (Don't Repeat Yourself) — principen som kräver att varje logisk enhet lagras på en plats. Om samma kod förekommer i flera delar av projektet — är det ett brott mot DRY. Åtgärd: flytta den repeterande logiken till en separat funktion, klass eller modul.
WET (Write Everything Twice) — motsatsen till DRY, där duplicering anses acceptabel. I WET-projekt kan samma kodfragment finnas i fem kopior och när kraven ändras korrigerar utvecklaren varje kopia separat. WET ökar risken för buggar och saktar ner utvecklingen.
DRY är skadligt vid förtida abstraktion: när två liknande men semantiskt olika koddelar tvångsförenas i en funktion. Detta skapar komplex, parameteröverbelastad kod. Rule of Three hjälper att undvika detta misstag: abstrahera först efter den tredje upprepningen.
I Android tillämpas DRY genom version catalog (libs.versions.toml), gemensamma basklasser för adaptrar, ViewModel-fabriker och användbara Kotlin-tillägg. Det rekommenderas att extrahera affärslogik till delade moduler (KMM) och använda View Binding för att eliminera findViewById-duplicering.
I iOS uppnås DRY genom protokoll med standardimplementering, gemensamma nätverkskonfigurationer (NetworkConfig), UICollectionView-cellfabriker och SPM-paket med delad affärslogik. Extensions av standardtyper (Date, String, URL) minskar duplicering av formatering och validering.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också