Løsningens Elegance
Det er meget let, når man arbejder inden for IT, at fokusere på store, komplekse løsninger. Det ser ud til, at det er her de gode løsninger befinder sig – store løsninger, masser af software, alle de nyeste gadgets. Det vi gør er spændende, og det er meget let at blive revet med af momentumet. Det’s sjovt at arbejde med udfordrende, store projekter. At høre hvad andre IT-professionelle gør, hvordan andre virksomheder løser udfordringer og at tale med leverandører med store systemer at sælge til os alle tilføjer spændingen, og det er meget let at miste fornemmelsen af omfang og mål – og det er så almindeligt at se store, overdrevne løsninger på simple problemer, at det ser ud til, at det bare er sådan IT fungerer.
Men det behøver det ikke at være. Kompleksitet er fjenden af både pålidelighed og sikkerhed. Unødvendigt komplekse løsninger øger omkostningerne både ved anskaffelse og implementering samt ved vedligeholdelse, mens de generelt er langsommere, mere skrøbelige og har en stor angrebsflade, der er sværere at forstå og beskytte. Simple, eller mere præcist, elegante løsninger er den bedste tilgang. Dette betyder ikke, at alle designs vil være simple, slet ikke. Komplekse designs er ofte nødvendige. IT er næppe et felt, der mangler kompleksitet. Faktisk menes det ofte, at softwareudvikling måske er det mest komplekse af alle menneskelige bestræbelser, i hvert fald dem der udøves i nogen skala. En typisk IT-installation inkluderer millioner af kodelinjer, hundredvis eller tusindvis af protokoller, et stort antal sammenkoblede systemer, lag af unikke softwarekonfigurationer, flere indstillinger end noget team overhovedet kan kende til, og først derefter tilføjer vi kompleksiteten af hundredvis eller tusindvis eller hundredtusindvis af uforudsigelige, irrationelle mennesker, der forsøger at bruge disse systemer, hver på en unik måde. IT er, uden tvivl, komplekst.
Det vigtige er at anerkende, at IT er komplekst, at det ikke kan undgås fuldstændigt, men at fokusere på at designe og konstruere løsninger, der er så simple, så elegante… som muligt. Denne designidé stammer fra, i hvert fald i min bevidsthed, softwareudvikling, hvor kompleks kode betragtes som en fejl, og simpel, smuk kode, der er let at læse og let at forstå, anses for vellykket. Et af de højeste hædersbevisninger, der kan gives en softwareingeniør, er at hendes kode anses for elegant. Hvor passende, at det tilskrives Blaise Pascal, efter hvem et af de mest populære programmeringssprog fra 1970'erne og 1980'erne var opkaldt, dette berømte citat (frit oversat fra fransk): “Jeg beklager, at jeg har måttet skrive dig et så langt brev, men jeg havde ikke tid til at skrive et kortere.”
Det er ofte langt lettere at designe komplekse, indviklede løsninger end at finde ud af, hvilken simpel tilgang der ville være tilstrækkelig. Uanset om vi har travlt eller ikke ved, hvor vi skal begynde en undersøgelse, er elegance altid en udfordring. Branchens momentum går i retning af at fremme den vanskeligere vej. Det er i leverandørernes interesse at sælge mere udstyr – ikke kun for at foretage det første salg, men de ved, at mere udstyr medfører flere supportindtægter, og hvis nok nyt, komplekst udstyr sælges, holder supportbehovet op med at stige lineært og begynder at stige geometrisk, da der er brug for yderligere support ikke kun til selve udstyret eller softwaren, men også til konfiguration og support af systeminteraktioner eller yderligere tilpasning. De finansielle incitamenter bag kompleksitet er store, og de stopper ikke med leverandørerne. IT-professionelle opnår stor jobtryghed, eller illusionen om den, ved at administrere store sæt af hardware og software, der er svære at overføre problemfrit til en anden IT-professionel.
Kompleksitet er ofte så forudsat, så forventet, at processen med at vælge en løsning begynder med stor kompleksitet som en given forudsætning uden nogen overvejelse af muligheden for, at en mindre kompleks løsning måske er tilstrækkelig, eller endda overlegen, ud over spørgsmålet om kompleksitet og pris i sig selv. Kompleksitet er nogle gange endda fuldstændig knyttet til visse koncepter i en sådan grad, at jeg faktisk har mødt vantro over den tanke, at en simpel løsning måske kan overgå en kompleks i pris, ydeevne og pålidelighed.
Retorik er let, men hvad er et eksempel fra den virkelige verden? De bedste eksempler, jeg ser i dag, er for det meste relateret til virtualisering, hvad enten det drejer sig om lagring, et cloud-administrationslag, software eller bare virtualisering i sig selv. Jeg ser ret ofte, at en samtale, der kun omhandler virtualisering for én person, umiddelbart medfører konnotationer om at kræve netværksbaseret, delt bloklager, dyr virtualiseringsstyringssoftware, mange redundante virtualiseringsnoder og kompleks software til høj tilgængelighed – ingen af disse er iboende i virtualisering, og de fleste er sjældent til gavn for eller egentlig engang i den virksomheds interesse, for hvem de vil blive implementeret. Frem for at arbejde ud fra forretningskrav opstår disse koncepter overvejende fra teknologiske forudindtagelser. Det er simpelt at pege på kompleksitet og fremstå som om man løser et problem – kompleksitet skaber en følelse af tryghed. Filtrer mange argumenter ned, og du vil høre “Hvordan kan det ikke virke, det er jo komplekst?” Kompleksitet giver en illusion af fuldstændighed eller af at have løst et problem, men dette kan ofte skjule, at en løsning måske ikke faktisk er fuldstændig eller engang funktionel, men graden af kompleksitet gør dette svært at se. Vores sind vil derefter ikke let acceptere, at en simplere tilgang er mere fuldstændig og løser et problem, når en kompleks ikke gør det, fordi det føles så kontraintuitivt.
Et godt eksempel på dette er, at vi tyr til at diskutere redundans frem for pålidelighed. Pålidelighed er svær at måle, redundans er simpel at kvantificere. En mursten er meget pålidelig, selv som enkelt element. Det kræver ikke redundans, at en mursten er stabil og robust. Dens design er simpelt. Du kunne lave en bærende konstruktion af mange redundante pinde, der slet ikke ville være nær så pålidelig som en enkelt mursten. Hvis du taler om pålidelighed – sandsynligheden for, at konstruktionen ikke fejler – er det klart, at murstenen er et overlegent valg frem for flere pinde. Men hvis du siger “men der er ingen redundans, murstenen kunne fejle, og der er intet til at erstatte den” lyder du tåbelig. Men når vi taler om computere og computersystemer finder vi systemer, der er så komplekse, at folk sjældent kan se, hvornår de har en mursten eller en pind, og da de ikke kan bestemme pålidelighed, som er det der betyder noget, fokuserer de på den let kvantificerbare redundans, som ikke gør det. Det hele system er for komplekst, men at søge den simple løsning, den der direkte adresserer kernen af problemet, kan reducere kompleksitet og give os et langt bedre svar i sidste ende.
Dette kan endda ses i RAID. Spejlet RAID er simpelt – blot en disk eller et sæt diske, der er en nøjagtig kopi af et andet sæt. Det er så simpelt. Paritet-RAID er komplekst med beregninger på en variabel stribe på tværs af mange enheder, der skal kodes ved skrivning og afkodes, hvis en enhed fejler. Spejlet RAID mangler denne kompleksitet og løser problemet med diskpålidelighed gennem simple, elegante kopieringsoperationer, der er meget pålidelige og velforståede. Paritet-RAID er unødvendigt komplekst og gør det skrøbeligt. Alligevel fremstår det derved og ved at underminere sin egen evne til at løse det problem, det er designet til, samtidigt som – tilsyneladende – mere pålideligt baseret på ingen anden faktor end sin egen kompleksitet. Det menneskelige sind hopper straks til “det er komplekst, derfor er det mere avanceret, derfor er det mere pålideligt”, men ingen af progressionerne er logiske. Kompleksitet antyder ikke, at det er mere avanceret, og det at være avanceret antyder ikke, at det er pålideligt, men det menneskelige sind er selv komplekst og let vildledt.
Der er intet simpelt svar på at finde simpelhed. At vide, at kompleksitet er dårlig af sin natur men uundgåelig til tider, lærer os at være opmærksomme, men det lærer os ikke, hvornår vi skal mistænke overkompleksitet. Vi skal være årvågne og altid søge at afgøre, om der findes et mere elegant svar, og ikke acceptere kompleksitet som det rigtige svar blot fordi det er komplekst. Vi er nødt til at sætte spørgsmålstegn ved foreslåede løsninger og stille spørgsmål til os selv. “Er denne løsning virkelig så simpel, som den burde være?” “Er denne kompleksitet nødvendig?” “Kræver dette den kompleksitet, jeg antog?”
I de fleste systemdesignanbefalinger, jeg giver, er det første tekniske afklaringstrin, jeg normalt tager, efter trinnet med at forhøre sig om det forretningsbehov, der skal løses, at sætte spørgsmålstegn ved kompleksitet. Hvis kompleksitet ikke kan forsvares, er det sandsynligvis unødvendig og modvirker aktivt det formål, den blev valgt til.
“Er det virkelig nødvendigt at opdele disse diske i mange separate arrays? Hvis ja, hvad er den tekniske begrundelse for at gøre det?”
“Er delt lager virkelig nødvendigt for den opgave, du foreslår det til?”
“Kan virksomheden virkelig retfærdiggøre brugen af distribuerede teknologier til høj tilgængelighed?”
“Hvorfor erstatter vi et simpelt system, der var tilstrækkeligt i går, med et dramatisk mere komplekst system i morgen? Hvad har ændret sig, der gør en stor forbedring, mens man forbliver simpel, ikke mere end nok, men kræver størrelsesordener mere kompleksitet og mere udgifter, der ikke var berettiget tidligere?”
Disse er blot almindelige eksempler – kompleksitet eksisterer i alle aspekter af vores branche. Søg simpelhed. Stræb efter elegance. Accepter ikke kompleksitet uden at vurdere den grundigt. Sæt den igennem den metaforiske vridemaskine. Lad ikke kompleksitet snige sig ind, hvor den ikke er berettiget. Fejl ikke til fordel for kompleksitet – når du er i tvivl, fejl simpelt. At oversimplificere en løsning resulterer typisk i en mindre fejl, mens det at gøre den unødigt kompleks åbner for en langt større grad af fejl. Det sikreste valg er den simplere løsning. Og hvis en simpel løsning vælges og viser sig utilstrækkelig, er det langt lettere at tilføje kompleksitet, end det er at fjerne den.
