Hvorfor jeg afskyr kompleksitet

Det forekommer mig at rigtigt mange software-problemer løses ved at tilføje kompleksitet. Det er en dårlig løsning. Jeg afskyr det.

Jeg har lige installeret et PHP-bibliotek fra Google i forbindelse med et Drupal-baseret projekt. Biblioteket gør det muligt at trække data fra Google Analytics over i ens egne rutiner, gemme dem, regne på dem, præsentere dem.

Det er smart, fordi Google Analytics ikke gør det særligt nemt for brugerne, at finde de data, de gerne vil have. Med mindre brugerne er ret øvede, altså. Desuden er der visse analyser som er svære at lave i Analytics. Ved at trække data ud kan man få data samlet eller delt og regnet på som man gerne vil have det.

Nå, men nok om det og tilbage til kernen i historien.

Googles Client Library <

Google tilbyder et lille PHP-eksempel, som viser hvordan man gør. Nemt nok: man henter eksemplet som er på under 50 kodelinier og lægger det på en server. Easy-peasy. Alt hvad man så mangler er Googles Client Library. Også ret let. Man henter nogle få filer på GitHub, lægger dem sammen med eksemplet.
Men så begynder dragen at stikke sit grimme, ildspyende hoved frem.
Første advarselstegn er at Composer skal i spil.

Composer er det nye sort i PHP. Composer er en såkaldt application-level package manager eller dependency manager som har til formål at holde styr på de programpakker som en given funktion har brug for.
En WYSIWYG-editor skal bruge nogle JavaScript-funktioner.
Billeder der vises i en popup skal bruge noget i stil med Colorbox.
Skal man have adgang til en Mongo-database skal man have nogle abstraktionsrutiner til at håndtere den forbindelse.

Engang var det nok at vide det. Så fandt man det nødvendige bibliotek, hentede det og installerede det og fyrede op under kedlerne. Typisk en ZIP-fil med en håndfuld filer, der blev pakket ud i en mappe, og så var alt godt.
Men tingene er ikke så enkle mere.
Afhængighederne er mere komplekse. Bibliotekerne følges nu af testfiler, include-filer, config-filer, talrige andre biblioteker, eksempler, profiler, templates, automatiske tests og al landsens andre mere eller mindre nødvendige eller rare godbidder.

Således også Googles Client Library.

5.600 filer, 349 mapper <

Efter at have kørt Composer som foreskrevet, lå der i min mappe med eksemplet nu en undermappe kaldet vendor.
I den lå der mere end 5.600 filer fordelt i 349 mapper!
Opah!

Den Drupal-installation, som dette skulle køre under – et helt CMS med brugerstyring, indholdshåndtering, temaer, design, hele molevitten – består i sin kerne af lidt mere end 1.100 filer i 149 mapper. Installationen af Googles bibliotek havde således lige gjort antallet af filer seks gange større! For at få een funktion, nemlig integration med Google Analytics.

Afskyeligt! Uartigt! Og ret sikkert unødvendigt...

Afskyeligt! Uartigt!

Et symptom <

Den lille oplevelse er ret symptomatisk for hvad der sker med meget kode og mange programmer for tiden. Jeg er en gammel hønisse, der kan huske dengang man kodede med effektivitet og minimalt ressourceforbrug som mål; talte bytes og endog bits, talte clock cycles og begrænsede og skar hvor det var muligt.

Det er sandt, at man ikke længere behøver at tænke i de baner i samme grad. Det forekommer mig bare at mange udviklere – både i forbindelse med programmeringsprocessen og i den resulterende kode – ser stort på ressourceforbruget og omfanget. De pøser lystigt styringsværktøjer, frameworks og kodebiblioteker ind i alle projekter uden at tænke over om det er optimalt.

Rækken er endeløs: SASS, Twig, JQuery, Git, Composer, Compass, Assetic, Symfony, Laravel, Bootstrap... Normen synes at være at man tilføjer et værktøj mere, et framework mere, et bibliotek mere for at løse de problemer, der er opstået som følge af den forøgede kompleksitet i projektet.
En mere fornuftig og rationel løsning ville vel være at fjerne noget og forsimple, eller...?
Måske er jeg bare for old school til at kunne forstå hvorfor det modsatte er smart. Jeg har svært ved at forstå hvordan det kan være en anprisning til et bibliotek at de skal installeres med Composer. Det er da nærmere et tegn på at det har vokset sig for stort til at overskue.

Større afstand, mindre indsigt <

Jeg kan sagtens se det besnærende i at bruge værktøjer og metoder som Composer, Git, SASS, Twig og andet til at automatisere og styre komplekse processer. Frameworks er også smarte. Der er ingen grund til at starte fra bunden hver gang. Mit problem med dem er bare, at de ikke altid forbedrer det indviklede, men bare skjuler det - og samtidig gør tingene mere indviklede og ofte leverer så meget mere end man har brug for.

Udvikleren slipper for at skulle vælge til og (ikke mindst) fra, slipper for at skulle tage beslutninger og slipper i mange tilfælde også for at skulle tænke kreativt. Den bevidstløse brug af færdige biblioteker og frameworks og køreklare værktøjer fjerner simpelthen udvikleren fra kernen, fratager ham eller hende viden, og dæmper indirekte lysten, muligheden eller viljen til at raffinere, optimere og rationalisere - og derigennem at lave bedre, enklere, mere effektiv og mere overskuelig kode.

Drupal 8000 <

Min yndlingsudviklingsplatform, Drupal, kom i en ny version i 2016. Drupal 7 blev til Drupal 8. Jeg har været med siden Drupal 4-komma-et-eller-andet, og derfra er det gået fremad med markante forbedringer fra version til version. Men forbedringerne har haft en pris.

Drupal 4 bestod af svimlende 103 filer i 13 mapper.
Tronfølgeren Drupal 5 lå omkring 275 filer i 50 mapper.
I version 6-dobledes filerne, men stadig kunne mappehierarkiet holdes på lige over 50.
Version 7 gav atter en fordobling, men nu i mere end 100 mapper voksende til næsten 150 mapper i den seneste opdatering.

OK, kompleksiteten var stigende og overblikket vigende... og løsningen?

Proudly presenting! Drupal 8: Drupal 8.3.6 består af 13.021 filer i 4.030 mapper! Seriøst! Ikke bare en fordobling i forhold til forgængeren, men fire gange så mange filer i næsten ti gange så mange mapper. Se det er noget, der kan give overblik!

Zip med vokseværk <

Et andet eksempel: Jeg skulle for nylig lave en Drupal-funktion, der kunne tilbyde download af alle originalfiler for en given nodes tilknyttede billeder. Der ville typisk være 5-10-20 billeder til en node, og jeg tænkte at det ville være passende at samle dem i en ZIP-fil og så downloade dem.

Der er masser af download-moduler til Drupal. Download, DownloadFile, File Download, ZipCart, pclzip og flere. De er ikke alle store, men alligevel. Flere af dem bruger pclzip, som er et bibliotek, der kan håndtere ZIP-filer.
De var alle overkill til mit brug.
ZipCart tilbyder endda en form for indkøbskurv til filer, med ”Cool JS animations if JS is enabled to see the downloaded item zoom to the cart.
Sådan en reklame giver mig kuldegysninger – og ikke af den gode slags. Det er ikke noget jeg gider slæbe med i min kode for at kunne zippe nogle filer.

Slet ikke fordi... PHP allerede kan zippe filer... uden videre!
Der er lavet en indbygget klasse i PHP som ganske kvikt og uden yderligere installationer kan zippe og unzippe filer.
Resultatet: en løsning på omkring 10 kodelinjer plus en 20-30 stykker til lidt husholdning. Alt sammen implementeret som en funktion i et eksisterende modul.
Simpelt, effektivt, kompakt.

Forenkling gennem opdeling <

Jeg er ikke helt blind for at man faktisk kan forenkle gennem at dele ting op i flere bidder, og at noget, der ligner mere kompleksitet, kan være en simplificering, der giver overblik.
  • Man kan dele store klumper kode op i mindre, logiske bidder.
  • Man kan samle beslægtede rutiner i include-filer.
  • Man kan isolere konfigurationsdata i egne filer.
  • Man kan lægge grafikfiler i en undermappe, så de ikke forplumrer billedet.

Alt sammen er en del af den udvikling som for eksempel Drupal er gået igennem. Men det alene kan ikke forklare vokseværket. Der er i processen også tilføjet mængder af eksterne biblioteker, nye funktioner, inddraget elementer, der før var tilvalg, og i det hele taget lagt rigtigt mange ting ind i den ellers ret rene og kompakte kerne.

Compile, link <

Igennem min opvækst og udvikling med programmering er der sket meget. Da jeg startede med at programmere Assembler, C og Pascal, skrev man sin kode i flade tekstfiler, compilede og linkede dem ved hjælp af komplekse kommandoer, som skulle skrives i hånden eller lægges i batch- eller make-filer.

Jeg husker åbenbaringen da Turbo Pascal kom frem. Jep, i 1984! Så gammel er jeg... Pludselig kunne man skrive koden, compile den, køre den, debugge den, alt sammen indefra det samme programmeringsmiljø. Ingen kommandoer, ingen make-filer, ingen heksekunster. Et tryk på en funktionstast og programmet kørte. Et tryk på en anden og der blev lavet en køreklar fil.
Det var et kolossalt fremskridt!

I dag hvor jeg hovedsagligt programmerer PHP er det i store træk det samme. Jeg arbejder i et miljø hvor der er intelligens i mit redigeringsprogram, hurtige afvikling af den færdige kode så snart den er gemt, brugbare fejlmeddelelser og adgang til en debugger, der hjælper med at luse fejl ud, og en profiler, der kan hjælpe med at finde langsomme rutiner.

Kommandoliniens tilbagekomst <

Men med fremkomsten af mange af de nye udviklingsplatforme, Drupal 8 som et af dem, men også de mange React-systemer, python-frameworks og andre systemer, så har kommandolinien fået en renæssance.
Adgangen til en velfungerende Unix-kommandolinie på moderne udvikleres yndlingsmaskiner – Mac'er – har gjort at selv den mest forhærdede MacOS-entusiast kaster lækre grafiske interfaces ud med badevandet og fyrer op under et klassisk prompt.

$ git clone git://github.com/django/django.git
$ php -r "readfile('http://files.drush.org/drush.phar');" > drush
$ composer create-project drupal-composer/drupal-project:8.x-dev my_site_name_dir --stability dev --no-interaction

Oh, lykke!
Slut med banale klik i letforståelige afkrydsningsbokse. Slut med at finde mapper med Finder eller Explorer. Slut med pæne farver, runde hjørner og skygger. Se det er et sandt fremskridt.

Jeg er ikke maskinstormer <

Misforstå mig nu ikke.
Jeg er ikke imod fremskridt.
Jeg modarbejder heller ikke udbygningen af systemer med nye og nyttige funktioner.
Jeg er heller ikke imod at bruge gammeldags metoder når de er bedre, nemmere og mere effektive.

Jeg har tit kommandolinien i sving på min maskine. Jeg er alt andet lige en gammel mand, der er vokset op med den og har fået den ind med min digitale modermælk. Men jeg er ikke sikker på, at jeg helt forstår hvorfor tingene skal blive mere komplekse, mere uoverskuelige, mere uforståelige og sværere at lære og bruge, når den teknologiske udvikling i almindelighed går imod at man kan styre alt med en tommelfinger fra en smartphone.

Vi sælger skamløst viden og assistance vedrørende