Överdesign är teknisk skuld

Det är inte svårt att inse att ett dåligt designat system har problem. Vi brukar kalla detta för teknisk skuld. För att städa upp i röran krävs en återbetalning av skulden i form av designförbättringar. En sak som inte pratas om så mycket är att även ett “framtidssäkert” (oj, det ordet ger mig fysiska rysningar), väldesignat system som väcker alla IT-arkitekters avund ofta lider av teknisk skuld. Hur då?

Underdesign

Begreppet teknisk skuld myntades av Ward Cunningham som en liknelse över det förfall, den “kodröta”, som våra mjukvarubaserade produkter och system under utveckling utsätts för. Förfallet finns i många former, till exempel duplicering av kod, kod som är svår att förstå, otestbar kod, kod med defekter samt kod som är bräcklig.

Om vi inte kämpar emot detta förfall kommer vår tekniska skuld att växa i takt med att vårt system blir allt mer komplext. Räntan på skulden betalar vi i form av lägre produktivitet, då utvecklarna tvingas arbeta trots eller runt dessa problem. Det är häpnadsväckande nog inte ovanligt att man ignorerar problemen och låter skulden växa så långt att systemet inte går att vidareutveckla längre. Man kan uttrycka det så att räntan är större än det kapital vi kan sätta in. Systemutvecklare brukar kalla detta för ett “legacysystem”; ett binärt vrak.

Bästa strategin för att betala av på den tekniska skulden brukar vara att aldrig låta den växa sig för stor. Agila team använder tekniker som refaktorisering, vilket innebär en ständig förbättring och vidareutveckling av vår design och kod utan att ändra dess externa beteende. Med refaktorisering kan vi till exempel se till att kalla saker vid deras rätta namn och att faktorisera koden i lagom stora sjok med tydliga, logiska ansvar.

Ovanstående resonemang brukar de flesta vara med på och förstå. För programmerare är det oftast glasklart: Om vi har många defekter i våra system, dålig kod eller design så har vi en teknisk skuld, punkt slut. Vi kan sammanfatta denna typ av teknisk skuld som underdesign. Med det menar jag att produkten är undermåligt designad. I dålig design lägger jag då även saker som defekter och kodkvalitet.

Överdesign

Det är lätt att tänka så här: Om underdesign leder till teknisk skuld borde jag alltså jobba stenhårt med att få till en generell och flexibel design som tar höjd och klarar alla rimliga framtida krav på produkten? Fel! Absolut inte.

Vad som händer när vi gör detta är nämligen något som vi kan kalla för överdesign. Överdesign innebär att vi har en design som inte bär sin egen vikt. Systemet är för komplicerat eller för generellt designat i relation till de krav som vi har på ett system. Ett system som ska betjäna 500 samtidiga bankkunder har inte samma krav på sin inre design som ett hemmabygge för att katalogisera sina filmer. Ganska självklart. Man kan se det så här: Överdesign innebär att vi har arbetat för hårt på systemets teknik i förhållande till dess nytta och användningssituation.

Ok, här kommer till slut min poäng: Även överdesign är skadlig för vårt system. Skälet till detta är att överdesign alltid innebär en större komplexitet, dvs en design som är generellare eller innehåller fler element och mekanismer än den behöver. Bara två saker kan hända med sådan extra komplexitet: 1. Den behövs, fast senare. Då har vi dragits med komplexitet i onödan under en period. 2. Den behövs aldrig. Då var arbetet dessutom onödigt till att börja med. Inget av fallen är önskvärda.

Låt oss ta ett trivialt exempel för att åskådliggöra. Ett projekt som jag har insyn i valde att kalla en passage som en bil gör vid en vägtull för en “transaktion” istället för något naturligare, till exempel “passage”. Visst, “transaktion” är en generellare term och användbar i flera sammanhang. Men det är också lite svårare att förstå. Varje gång någon läser ordet “transaktion” måste personen göra en översättning i huvudet till “passage”. Vi har skapat ett mentalt avstånd mellan namnet och vad det representerar. Det kan låta som en löjlig sak, men multiplicera detta med varje term och varje gång det händer och vi inser att vår förståelse av systemet är skadad.

Vi fortsätter resonemanget: Högre komplexitet betyder i sin tur något lägre produktivitet. Om en del i systemet är mer komplicerat designad så är den också svårare att förstå och arbeta med. Om vi till exempel har överanvänt designmönster så är kanske systemet lite flexiblare men det är också svårare att förstå. När något är svårare att arbeta med än det behöver vara får vi lägre produktivitet än vi behöver ha. Vi kan givetvis förbättra vår situation genom att i det här fallet förenkla vår design, göra den mer naturlig och smidig att arbeta med.

Hm, det här resonemanget känner vi igen. Den kanske något förvånande slutsatsen är att överdesign också är en form av teknisk skuld.

Lagom design

Idealet för en design är varken underdesign eller överdesign utan en balansering på slak lina däremellan. Vi kan kalla det för lagom design. En lagom design är så enkel som möjligt; lätt att förstå, faktoriserad och minimal, men inte enklare. Det är vårt ideal att sträva efter.

En följdsats till detta är att när vi bedömer en design måste vi relatera den till de krav som vi har på systemet. Det finns helt enkelt ingen objektivt bra design, bara bra design relaterat till behoven. Tänk på det nästa gång någon slänger ett komplicerat klassdiagram i ansiktet på dig och väntar på ditt smackande beröm.

3 thoughts on “Överdesign är teknisk skuld

  1. Hehe, exemplet känns vagt bekant…

    Jag tycker att det är en intressant iaktagelse att man som systemdesigner numer inte ska sträva efter “den bästa designen” med en massa patterns till hjälp, utan istället sträva efter den “den mest lagoma designen”. Det är lite utav en ny sorts hantverkskunnande. Den klassiska arkitekten måste bli mer aktiv i teamet och kontinuerligt coacha sina medutvecklare till att ständigt ha uppmärksamhet på designodörer och refaktoriseringsmöjligheter.

    Fin artikel!

  2. Tänkvärt som vanligt! Exemplet känns även som ett exempel på vikten av rätt domänspråk, som vi ju undersökte en del i kursdatabasen på KTH …

  3. Intressant! När jag läste första delen av under design kom jag direkt att tänka på den här postningen: http://danielbrolund.wordpress.com/2008/09/16/elastic-plastic-and-fracture-characteristics-of-code/

    I någon mån följer kodröta fysikens lagar.

    När jag läste vidare om överdesign blev kopplingen till det jag gör just nu väldigt stark. Vi har upptäckt att en del av kodensom jag själv skrivit *rodnar* kan göras väsentligt mycket enklare. Det som tidigare var ett ganska komplicerat maskineri blir nästan ingenting om man tänker lite anorlunda.

    Det lustiga var att den delen som uppenbarligen är överdesignad nu var revulotionerande effektiv och ett av de största lyften vi har haft i projektet i form av möjlighet att produktionssätta ofta. Och den del som den nu överdesignade koden vid ett tillfälle ersatte sågs då som överdesignad.

    Frågan är när bättre insikter dömer ut det jag gör just nu? Hoppas att det blir så en dag! Jag tror att flow är viktigare än lagom deignnivå och att lagom design är något man landar i efter några vändor av både under och överdesignande. Man “svänger in sig” till rätt nivå så att säga genom att göra, reflektera och sedan göra igen.

    Tack för en bra artikel!

Comments are closed.