The computer is the most profound machine that we humans have ever created and ever will create. In the late 1940'ies, it was the newest and most advanced, but not essentially different from the other machines of the machine age, which had started cirka 200 years earlier with the invention of the steem engine. But it would soon come to rule them all and mark the beginning of a new age.

Before 1950, computers were operated, much like other machines, by connecting wires, pressing buttons and pulling levers. But by 1950 the operator no longer controlled the computer harware directly. Instead a new layer of abstraction, called software, had emerged, which was manipulated though special input and output devices. This hardware-software separation is what marks the transition into the new era of computers.

Since then there has been a major breakthrough in our relation with computers aproximately every nine years. I predict that apart from the eight milestones we have already passed, there will be five more, after which the computer age is over.
 
These are the milestones of the computer age:

1950: The human computer interface: The computer age dawns when software is clearly separated from hardware. The computer is operated by manipulating its software and studying its output through a human computer interface - typically consisting of a typewriter, a printer, punchcards and magnetic tapes.
1959: The terminal: The typewriter and printer are combined into an electronic device that can send input directly to the computer and present the output immediately on a screen
1968: The display: The advance of computer graphics makes it possible to display an abstract representation of a program state in both textual and graphical form. The program state can be directly manipulated through input devices such as the newly invented computer mouse.
1977: The personal computer: Computers have become sufficiently small, cheap, powerful and easy to use, that many people want to own a computer. From being exclusive to large coorporations and science labs, it now makes its entrance into regular homes and offices. TV-screen, keyboard and mouse become the standard human-computer interface.
1986: The portable computer: All parts of the computer can now be integrated into a foldable case that can be carried around. You no longer have to sit down by a desk to use a computer.
1995: The online computer: Both the Internet and the world wide web have existed for a while, but this year it reaches the mass market. The internet boom coincides with the multimedia boom, giving the large public a rich experience of graphics and sound, both online and off-line.
2004: The mobile computer: Smartphones are taking over the mobile phone market and the iPhone is just a couple of years away. Everyone can now have a computer in their pocket.
2013: The ubiqitous computer: The most recent breakthrough, cloud computing, is less appearent for the end user, but it revolutionises creation and hosting of web applications. Most traditionally desktop based applications move to the cloud for a greater collaborative online experience.
2022: The wearable computer: The computer no longer has to be something you carry with you - you weare it; as a watch, glasses, jewelry or even implants. It is powerful enough on its own but can also connect seamlessly with the cloud and devices around it. Screens are cheap and expendable. They can be folded, laser projected or even generated on demand.
2031: The etheral computer: The cloud moves out from the massive data centers and into micro-servers all around us, connected wirelessly with eachother. It is no longer meaningful to talk about data as stored in a specific number of copies at specific physical locations. Instead we measure data in terms of accessibility and integrity.
2040: The neural computer: Naturally we will want to interface with the computer without the bother of having external devices that only can be accessed though sensory input and output. In the beginning of the 2040's, the techology is finaly ready to connect us to the computer directly on the nerves. We will be able to see, hear, smell, taste and feel the computer state and control it by pure thought.
About the same time, unemployment in the developed part of the world exceeds 50%
2049: The symbiotic computer: The separation between human and computer is getting more fuzzy as large parts of our brain are connected directly to the computer. We can no longer survive without it. 
2058: The sentient computer: As human and computer fully merge into one speices, the symbiots, the computer becomes self-aware, but on a level that we cannot comprehend. If the human brain survives it will have the same relationship to the computer as our reptile brain has to the celebral cortex. Whatever part of our bodies that are needed to sustain whatever part of our brains that will be left, survives. The rest dissapears.
2067: The end of the human race: The naturals, those humans who decides to stay un-augmented by computer power, is enslaved and later exterminated as their utility for the symbiots subseedes the cost of keeping them alive.

Alla som har jobbat i Scrum, och det har väl de flesta av oss vid det här laget, har säkert ställt sig frågan: Vilken uppgift ska jag ta mig an härnäst?

Den mer generella frågan, som den här bloggposten vill ge ett svar på, är: Hur ska uppgifterna i backloggen prioriteras mot varandra?

Det här brukar vara mer konst än vetenskap och man gör det lite på känn; vid behov, när det finns tid över, eller vid särskilda prioriteringsmöten. Aspekter som brukar vägas in är hur lång tid uppgiften tar, hur viktig den är och kanske även dess svårighetsgrad.

För att försöka lösa det här problemet en gång för alla har jag identifiera fem olika kriterier som jag anser bör vägas in i bedömingen. Vidare har jag rangordnat dessa kriterier mot varandra och slutligen har jag satt ihop dem till en formel som tar hänsyn till rangordningen och som ger en totalsumma att prioritera efter, utifrån hur många poäng man satt på varje dimension.

Alltså: Istället för att sätta upp fingret i luften och känna efter hur uppgifterna bör prioriteras, bedömmer man dem enskilt i fem olika dimensioner och räknar sedan fram en inbördes rangordning.

De fem kriterierna är som följer:

  1. Funtamentalitet
    - det första kriteriet har att göra med hur central för systemets ändamål en uppgift är. Jag anser detta vara det viktigaste kriteriet. Ett system bör byggas inifrån ut. Om inte kärnfunktionaliteten fungerar tillfredställande spelar det mindre roll hur bra kringfunktionerna är. Lägger man för stor vikt vid kringfunktioner så kanske man utvecklar fel system och borde istället utveckla ett system där kringfunktionerna är centrala. Alltså; börja med fundamental funktionalitet och gå sedan mot allt mer perifera funktioner när det mer basala finns på plats och fungerar som det ska

  2. Enkelhet
    - För att undvika att bygga på den tekniska skulden så bör man som nummer två värdera hur en uppgift påverkar systemets totala komplexitet. Om det finns uppgifter som minskar den totala komplexiteten eller åtminstone inte ökar den så bör man ta dem före uppgifter som ökar komplexiteten. Jobbar man i den riktningen så skapar man allt hållbarare fundament som kan bära upp en allt större funktionell överbyggnad. Annorlunda uttryckt: De uppgifter som idag adderar mycket komplexitet kan imorgon addera liten eller ingen komplexitet om man först har förstärkt och renodlat fundamenten/koncepten.

  3. Värde
    - Först på tredje plats har jag rankat det som vid första anblicken kan tyckas vara det viktigaste kriteriet, nämligen hur stort värde en funktion adderar till systemet. Anledningen är att ett IT-system är som ett isberg; den lilla synliga toppen motsvarar funktionalitet som ger ett direkt värde för kunden och allt annat är stödstrukturer som krävs för att bära upp de värdebärande funktionerna. Efter hand som ett system växer sig större och mer komplext minskar den värdebärande funktionalitetens andel av den totala massan. Om man bara satsar på att addera värde så riskerar överbyggnaden att bli större än vad fundamentet kan bära upp och hela systemet kollapsar under sin egen tyngd. Därför bör fundamentalitet och komplexitet värderas över värdeskapande.

  4. Svårighetsgrad
    - svårighetsgrad är i stort sett ekvivalent med risk: Risk att man inte hittar någon som är kompetent nog att utföra uppgiften, risk att oväntade problem uppstår under utvecklingen, risk att funktionen skapar nya buggar, och risk att man har missbedömt någon av de andra kriterierna. Därför bör svårighetsgraden vägas in när man prioriterar uppgifter. Börja med det som är enkelt. Ju längre arbetet framskrider desto mer erfarenhet samlar utvecklarna och ju starkare fundament finns att bygga mer komplicerade funktioner på. Bygger man rätt så tenderar svåra uppgifter som man skjuter på framtiden att te sig allt enklare med tiden och kommer därför prioriteras allt högre, allt annat lika.

  5. Tidsåtgång
    - Sist och faktiskt minst väsentlig är tidsåtgången. I de flesta IT-projekt beror en överhängande del av tidsåtgången på att man får betala för gamla synder, det vill säga handskas med teknisk skuld. Det kan röra sig om så mycket om en faktor tio eller en faktor hundra i tidsskillnad mellan att bygga en funktion på ett starkt och väl underhållet fundament och att bygga den på ett svagt och överkomplext fundament. Därför blir tidsåtgången ofta mer en funktion av hur väl underhållet systemet är än en funktion av hur stor uppgiften är. Icke desto mindre bör naturligtvis tidsåtgången beaktas eftersom effektiviteten i utvecklingen totalt sett är en funktion av värde delat med tid.

Man poängsätter alltså varje uppgift efter var och en av ovan beskrivna dimensioner. Sedan summeras poängen, och uppgifter med lägre poäng prioriteras före uppgifter med högre poäng.

För att väga in rangordningen mellan dimensionerna så har de olika skalor, där de viktigare dimensionerna har fler poäng att fördela än de mindre viktiga. Närmare bestämt har Fundamentalitet sju poäng att fördela, Enkelhet sex poäng och så vidare, ner till Tidsåtgång som har tre poäng. Varför en kortare poängskala ger en mindre total vikt i sammanräkningen behöver kanske motiveras. Man kan tänka så här: Differensen mellan minsta och största poäng är mindre ju kortare skalan är, alltså ger en kortare skala en mindre addering till totalsumman. 

Poängskalorna är som följer:

Fundamentalitet:

1: Fundamental
   - utan vilken systemet inte kan köras

2: Essentiell:
  - utan vilken systemet inte är ändamålsenligt

3: Kärnfunktion
 - utan vilka systemet inte kan anses fullt funktionellt

4: Basal funktion
 - utan vilka systemet inte kan anses komplett

5: Extra funktionalitet
 - som lägger till det som behövs i anslutning till det basala och gör systemet fullödigt

6: Nice to have / bra att ha

 - som ytterligare förbättrar systemet

7: Goldplating / Förgyllning
 - som adderar det lilla extra, t ex snyggare layout, grafiska effekter eller arbetsbesparande extra kommandon.

Enkelhet:

-2: Väsentlig förenkling

-1: Viss förenkling

0: Ingen förändring i komplexitet

1: Viss komplexitetsökning

2: Väsentlig komplexitetsökning

3: Mycket stor komplexitetsökning

Värdeskapande

0: Skapar inget direkt värde för användaren (refaktorering)

-1: Litet värde

-2: Medel värde

-3: Stort värde

-4: Mycket stort värde

Svårighetsgrad:

1: Trivialt

2: Enkelt

3: Medel

4: Svårt

Tidsåtgång:

1: Kort (minuter)

2: Medel (någon eller några timmar)

3: Lång (många timmar eller flera dagar)

Genom lite huvudräkning får man snabbt fram att totalsumman som man prioriterar efter kan variera mellan -3 och +17, alltså en total differens på 20; där Tidsåtgång adderar 2, Svårighetsgrad 3 och så vidare, upp till Fundamentalitet som adderar 6 steg.  

Slutligen:

  • En uppgift som är mycket svår ska inte utföras direkt, istället ska man titta på vilka förändringar i fundament och arkitektur som krävs för att förenkla uppgiften

  • En uppgift som tar lång tid (3 poäng) ska alltid delas upp i mindre uppgifter som värderas var för sig och prioriteras mot övriga uppgifter på nytt

  • Uppgifter kan ha beroenden som dikterar i vilken ordning de måste utföras. I sådana fall är det den högst rankade uppgiftens rangordning som bestämmer när andra uppgifter som den är beroende av ska utföras.

  • En uppgift som har ett positivt värde om man summerar enkelhet och värde (alltså skapar mer komplexitet än värde) bör tas bort från backloggen. En uppgift där enkelhet + värde = 0 bör noga övervägas vilket problem den löser och om problemet kan lösas på ett sätt som samtidigt ökar systemets samlade värde och potential (= enkelhet). Om inte bör en motivering till varför uppgiften är värd att utföras skrivas in på uppgiftskortet. 
Den ovan beskrivna metodiken / algoritmen är förmodligen lite för hardcore för de flesta Scrum/Kanban-projekt, men i stora projekt där prioritering mellan många uppgifter under tajta tidsramar blir ett stort huvudbry för projektledare och scrummästare kanske den kan tjäna som inspiration, eller rent av går att tillämpa rakt av.
Artefakt betyder "konstgjort föremål". De uppstår inte av sig själva eller utifrån naturliga processer. Det finns alltid en intention bakom en artefakt. En artefakt kan inte heller fullständigt förklaras utifrån den miljö och det sammanhang den kommer ifrån. För att fullt ut förstå en artefakt måste man fråga dem vars intention ligger bakom skapandet av den.

Vår civilisation är uppbyggd av artefakter. Utan dem hade vi fortfarande gått runt på savannen och samlat kottar. Artefakter har uppenbarligen sina fördelar: Vi har hus som vi kan vila i när vi har gått på savannen och samlat kottar en hel dag. Vi har prydnadshyllor att lägga kottarna på, och vi har bilar så att vi kan nå längre ut på savannen och hämta de större och finare kottarna som finns längre bort, bara för att ta några exempel. Men i programkod är artefakter av ondo. Perfekt ren kod är fri från artefakter. Perfekt ren kod är självförklarande, eller som Ward Cunningham uttrycker det i Robert C. Martin's bok Clean code: "Du vet att du arbetar med ren kod när varje rutin du läser på det hela taget är vad du förväntar dig".

Kod som är självförklarande, eller "på det hela taget vad du förväntar dig" utifrån sammanhanget och kraven, har inga artefakter. Hade där funnits artefakter så hade det också funnits behov av förklaring. Artefakter föder artefakter, vilket är orsaken till att kod som inte hålls perfekt ren med tiden blir allt mer tungarbetad. En illa döpt variabel är en artefakt, liksom den extra kommentaren som behövs för att förklara den. En överdesignad arkitektur är en artefakt, liksom den extra kod som krävs för att uppfylla den. Kod som innehåller artefakter rostar med tiden, medan ren, naturlig kod håller sig frisk genom att ny kod får spira i gammal kod som multnar bort i ett ständigt kretslopp.

Att känna igen en artefakt är inte det lättaste, vilket förklarar varför även den mest samvetsnoggranne programmeraren har så svårt att hålla sin kod ren. Alla har sina fix och trix, förkärlekar och käpphästar, som kan kännas fullständigt naturliga för en själv men för andra framstår som de artefakter de är. Någon kanske vill ha ett kommentarsblock före varje metod, oavsett om det står något i det eller inte, eller en kommentar om varje in- och utparameter, oavsett om de tillför förklaringsvärde eller inte. Sådant är artefakter. Någon annan kanske inte tycker det är så noga om det finns en eller två eller tre radbrytningar mellan metoder och block, eller om en och annan bortkommenterad kodrad ligger kvar. Men varje onödigt tecken är skräp, a.k.a. rester av en artefakt. Ytterligare någon kan ha en förkärlek för fabriker och gränssnitt. Men om varje klass har sin egen fabrik och sitt eget gränssnitt så är det mycket troligt att några av dessa är artefakter.

Det enda sättet att upptäcka artefakter i sin egen och andras kod är genom kodgranskning. Att granska sin egen kod före varje incheckning och ta bort de artefakter man hittar är nödvändigt, men inte tillräckligt. Vi måste också granska varandras kod. Ju mer olik din och din kollegas kodstil är, desto nyttigare är det att ni granskar varandras kod. Incheckad kod ska se ut som om den hade uppstått som en naturlig följd av de interna och externa krav den har att uppfylla. Incheckad kod ska vara fri från personlig stil, fri från artefakter. En professionell programmerare avhåller sig från att sätta sin personliga prägel på koden. "Don't be clever". "Don't be cute."

För att hålla sin kod fri från artefakter måste du hålla ditt ego utanför arbetet. Det är inte din intelligens som skapar koden. Det är kraven som skapar koden. Du är endast jordmånen som tillåter koden att växa. Du vill att koden ska växa sig så rak och stark som möjligt för att uppnå sin fulla potential. Men försöker du styra den så böjer du den bara. Du kanske är expert på WCF, MVC, SQL, eller någon annan TBA. Bra! Det ger koden en rikare jordmån att växa i; Men låt koden välja var den vill växa utan att försöka påverka den. Lämna alltid ditt ego och dina egna ambitioner utanför processen. Och lyssna på dina kollegor som pekar ut de artefakter som just du är blind för.
 
Tack vare missionärer som Robert C. Martin är vi idag många som är medvetna om värdet av att hålla koden ren och fin. Men frågar man två programmerare så är det troligt att de har olika upfattningar om vad ren kod är, eller vad som är ren kod. Om vi flyttar fokus från kodens renhet till hur vi kan frigöra koden från artefakter så blir problemet mer konkret och därmed lättare att lösa. Artefakterna ger svaret på frågan vad som är ren kod och varför vi behöver kodgranskning vid sidan av testtäckning för att hålla koden ren. Så nästa gång du stöter på en artefakt i din eller någon annans kod, fundera på om den alls behövs, och i så fall, vilken som är den naturliga konstruktionen som den kan ersättas med. Med varje artefakt som koden befrias ifrån blir den lite renare, och om du alltid checkar in koden med åtminstone inte fler artefakter än den hade när du checkade ut den så har du receptet för ren kod och ett lyckat projekt.