Softwareudviklere er gode til at genkende mønstre. Måske er det en iboende evne, der trækker os til dette erhverv. Eller måske er det processen med at skrive software, der udvikler denne evne. Uanset hvad, så er “don’t repeat yourself” (DRY) en naturlig anvendelse af denne evne.
Og dog er gentagelse i sig selv ikke den fjende, som dette princip gør det til.
- Don’t Repeat Yourself
- Something Repeat Yourself
- Spørgsmål at stille
- Er dette et enkelt stykke viden, der er blevet dubleret, eller er det bare infrastruktur, der tilfældigvis ligner hinanden?
- Hvor mange gange er denne ting blevet gentaget?
- Vil reduktionen af gentagelser nu gøre det sværere at tilpasse de enkelte tilfælde i fremtiden?
- Hvis jeg reducerer denne duplikation, hvad er så forholdet mellem abstraktionens størrelse og antallet af parametre, som den vil tage?
- Slutning
Don’t Repeat Yourself
Så intuitivt som “don’t repeat yourself” kan være, opsummerer The Pragmatic Programmer det på denne måde:
Hvert stykke viden skal have en enkelt, entydig og autoritativ repræsentation i et system.
Det er ikke svært at forestille sig fordelene ved at reducere eller eliminere gentagelser.
- Mindre gentagelser betyder mindre kode, der skal vedligeholdes. Og hvis den bedste kode er ingen kode overhovedet, lyder det som en god ting.
- En enkelt sandhedskilde eliminerer muligheden for, at tingene ikke bliver synkroniseret. En eller anden forretningsregel er ændret? Opdater den ét sted, og så er du færdig.
- Kode kan genbruges. Har du en proces, der deles af tre ting, og skal du tilføje en fjerde? Det meste af arbejdet er allerede gjort.
Something Repeat Yourself
Det kan skabe flere problemer, end det løser, hvis du er for ivrig efter at reducere tilsyneladende dobbeltarbejde. Jeg siger “tilsyneladende overlapning”, fordi nogle gange er ting, der ser ens ud, faktisk ikke relateret til hinanden. F.eks. kan to datastrukturer med identiske egenskaber og typer være de samme strukturelt, men ikke semantisk.
En almindelig strategi til at reducere dobbeltkode er at udpege de fælles dele og skjule dem bag en abstraktion. Men en uønsket bivirkning af dette er, at det kobler alt, der bruger abstraktionen. Enhver ændring i abstraktionen påvirker alle dens forbrugere. Og på samme måde kan det være nødvendigt at bøje abstraktionen for at opfylde kravene hos blot én forbruger.
Denne øgede kobling er også forbundet med et fald i fleksibilitet. Lad os sige, at du har en proces, der bruges tre steder. Den er næsten den samme alle tre steder, med blot nogle få vigtige forskelle. Så du implementerer processen som et enkelt modul, der tager et par parametre for at dække forskellene.
Det er nu umuligt at justere processen for blot et enkelt af disse brugssituationer: enhver ændring af den ene påvirker alle tre. Selvfølgelig kan man tilføje flere parametre (eller specialtilfælde!), efterhånden som brugssagerne afviger fra hinanden. Men det vil hurtigt blive umuligt at skelne de vigtige dele af processen fra den infrastruktur, der adskiller use cases.
Spørgsmål at stille
Når jeg refaktoriserer eksisterende kode eller skriver ny kode, der potentielt kan være dubleret, spørger jeg mig selv:
Er dette et enkelt stykke viden, der er blevet dubleret, eller er det bare infrastruktur, der tilfældigvis ligner hinanden?
Så du har rodet dig igennem CSS og fundet en klasse, der tilfældigvis har de stilarter, du ønsker. Det er nok ikke en god nok grund til at undgå at definere endnu en klasse.
Hvor mange gange er denne ting blevet gentaget?
Sådan længe en virkelig overflødig ting ikke optræder mindst tre gange, ville jeg være meget skeptisk over for enhver gentagelsesreduktion, der øger kompleksiteten.
Vil reduktionen af gentagelser nu gøre det sværere at tilpasse de enkelte tilfælde i fremtiden?
Der er noget tilfredsstillende ved at refaktorisere en masse copy-and-paste-kode til noget mere strømlinet og genanvendeligt. Men at låse koden så stramt, at enhver ændring vil indføre specielle tilfælde, er ikke en god afvejning.
Hvis jeg reducerer denne duplikation, hvad er så forholdet mellem abstraktionens størrelse og antallet af parametre, som den vil tage?
Biblioteker og frameworks er fantastiske, fordi de giver genanvendelig kode med relativt få parametre til tilpasning. Men forestil dig en applikationsspecifik funktion til præsentation af en dialogboks, der er vokset og nu accepterer 20 parametre. Den fordel, der var ved at reducere gentagelser, da den havde 2 parametre, er ikke længere til stede.
Slutning
Som med mange principper for softwareudvikling er “gentag ikke dig selv” mere en retningslinje end et mantra.