2 September 2008

Överdesign är teknisk skuld

Posted in Systemutveckling tagged , at 22.15 by Joakim Holm

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.

8 March 2008

TDD-kursen igång

Posted in Systemutveckling tagged , at 16.16 by Joakim Holm

Jag och Måns Sandström är väldigt stolta. Vi har nämligen dragit igång vår TDD-kurs på allvar nu och haft vår första kompletta kunddragning (introduktion, för utvecklare och för kravhanterare). En hel höst av förberedelser som äntligen har fått sättas på prov. Naturligtvis är det ganska tufft att hålla kurs samtidigt som man har andra uppdrag på heltid (jag har fått gå ned lite i tid) men det är också väldigt givande och lärorikt. Bara att diskutera igenom alltihop på djupet med en annan utvecklare ger många insikter.

Den svåraste utmaningen som vi har upptäckt hittills är att när vi beskriver den testdrivna miljö vi vill se i utvecklingsarbetet så reagerar ibland deltagare med både entusiasm och med tvivel därför att det ligger så långt ifrån deras egen verklighet, med gamla produkter, seg organisation och trögjobbad kod. Det är lätt att tänka att vårt budskap är orealistiskt, när vi hellre vill att de ska tänka: “Vilka steg kan jag börja ta för att närma mig detta som jag egentligen tror är bra?”. Det blir en utmaning för oss i våra kommande kurser.

Är du intresserad av att bli duktig på TDD så kommer vi att ge en publik kurs om en knapp månad och förhoppningsvis även i höst. De publika kurserna sker i samarbete med Jaybis. Läs mer om kursen på Jaybis webbplats. Där kan du också anmäla dig.

15 December 2006

Reflektion över destillation

Posted in Systemutveckling tagged at 18.23 by Joakim Holm

Jag läste nyligen ut boken Domain-Driven Design (DDD), av Eric Evans. I ett av kapitlen tar Eric upp “Destillation” som ett av stegen i hur man når en uttrycksfull och djup modell av verkligheten. Det innebär, som jag tolkar det, att ständigt arbeta med design, att våga tänka om och att ständigt förfina och förenkla sin modell av verkligheten.

Enligt boken och även min egen erfarenhet är det dock något som sällan sker i utvecklingsprojekt. Ofta stannar vi vid den första designen som ser ut att fungera. Den är i bästa fall en naiv, okunnig bild av domänen – i andra fall helt felaktig. Vi kanske till slut får mjukvara som fungerar, men den är inte fantastisk.

Hur som helst, kapitlet om destillation fick mig att fundera på om inte allt kreativt arbete har inslag av två faser: Ett kreativt skapande och ett analytiskt destillerande.

Låt mig ta ett exempel: Antag att du ska skriva en text för din blogg (surprise!). Många, inklusive jag själv, arbetar på så sätt att vi först försöker få ner alla relevanta tankar vi har om ämnet, därefter låta texten vila något, för att därefter förfina och förkorta texten i ett eller flera pass. Målet är säga exakt det man vill ha sagt (maximal uttrycksfullhet) på kortaste, elegantaste sätt (maximal förståelse och tillgänglighet). På samma sätt som i Evans’ DDD innehåller denna uppgift två distinkta faser.

Ett annat exempel som omedelbart dyker upp i huvudet är brain-storming. Många känner till reglerna för brain-storming, men inte alla känner till att den egentligen ska göras i flera omgångar. Först, kreativt spekulerande och idéskapande, därefter ett kritiskt förfinande och selekterande. Och gör om tills vi är nöjda. Precis samma sak.

Annat exempel: Kodning och refaktorisering sägs visserligen göras “kontinuerlig”, men sanningen är ju att vi systemutvecklare arbetar i två modus: 1. Få till kod som löser uppgiften vi har framför oss, och 2. förfina koden för maximal förståelse, uttrycksfullhet och återanvändning. Samma sak fast kortare faser.

En fråga man kan ställa sig då: Varför två distinkta faser? En teori kan vara att våra hjärnor inte är kopplade för att tänka kreativt och analytiskt på samma gång. Det är nästan som en slags andning. Andas in: Sätt igång hjärnan på maximal kreativt läge. Andas ut: Betrakta det du har fått fram som om du aldrig har sett det förut. Utmana det för att hitta de absolut bästa tankarna. Det är svårt att att andas in och ut samtidigt.

Som norrlänningen sa: Destillation är en del av livet.

Follow

Get every new post delivered to your Inbox.

Join 811 other followers