Degenen die zijn opgegroeid met de analoge beeldbuis-televisie kennen het wellicht nog wel: als de tv weer eens kuren had, gaf pa een welgemikte klap op de zijkant van het toestel, en zowaar: hij deed het weer. Het probleem van deze aanpak was alleen wel dat na te veel klappen, de tv het echt begaf, en er dure reparatie nodig was om de echte oorzaak op te sporen en te repareren.
Afgelopen jaren heb ik me onder andere veel beziggehouden met configuration- en buildmanagement. Als daar iets niet werkte heb ik ook menig variant op de service-klap uitgedeeld zien worden om de omgeving weer aan de praat te krijgen, zonder daarbij naar het echte probleem te kijken.
Enkele voorbeelden uit de praktijk:
- Een klassieker die de meesten wellicht wel kennen: het gebruik van hardgecodeerde paden omdat men niet weet hoe of welke variabelen te gebruiken om bijvoorbeeld de juiste sdk te gebruiken
- In het verlengde hiervan: ontwikkelaars die dll’s van externen in het archief zetten in plaats van de sdk te installeren en gebruiken. Dit werkt, totdat je collega zijn sdk gaat updaten en dit geen enkel effect heeft omdat deze niet gebruikt blijkt te worden
- Soms krijg je een nieuwe versie van een interface aangeboden, en dan bouwt een stukje van jouw code niet meer. In plaats van de code aan te passen, werd voor betreffende module terug gesprongen naar de oude interface, en voor de rest van de code weer naar de nieuwe. De code was dus niet meer tegen één, maar tegen twee versies van de interface aan gebouwd. In de lijst van gebruikte interfaces daarentegen stond maar één versie genoemd
- Sommige versie-beheerssystemen hebben de eigenschap dat de bestanden die je ziet standaard op ‘alleen-lezen’ staan. Deze systemen kennen commando’s om alle gegenereerde bestanden weg te gooien, maar ‘del *.*’ werkt natuurlijk ook. Bij migratie naar een ander versie-beheerssysteem (waarbij de bestanden niet op ‘alleen-lezen’ staan) bouwde de software niet meer, omdat voor betreffende directory nu niet alleen de genereerde bestanden, maar ook de broncode weggegooid werd.
- Na een upgrade van een compiler gaf deze op een bepaald stukje code een melding waar de ontwikkelaar van deze code het absoluut niet eens was. Hij maakte daarom een wrapper rondom de compiler die hetzelfde deed, maar betreffende melding afving. Pas ruim een jaar later, toen we een nieuwe bouwomgeving niet aan de gang kregen vanwege deze melding, kwamen we hier achter
- Om de logfiles een beetje compact te houden, had een ontwikkelaar bedacht dat voor bouwstappen die volgens hem toch nooit fout zouden gaan, de output niet gelogd hoefde te worden (redirect naar /dev/null). Na wat vernieuwingen in de omgeving werd de software niet meer goed gebouwd, maar de logfile liet niets raars zien….
De vraag waar ik na al die jaren echter nog steeds geen antwoord op heb, is waarom dit soort keuzes gemaakt worden. Is het onwetendheid, is het onwil, is de doorlooptijd van een bouw belangrijker dan de kwaliteit, wil men koste wat het kost iets werkbaars laten zien aan het einde van de sprint?
Wat ik ondertussen wel weet is dat dit soort workarounds, net als de service-klap van vroeger, vroeg of laat dure correctie-acties (reparaties) tot gevolg heeft. Ik schud de voorbeelden nu makkelijk uit mijn mouw, maar sommige van bovenstaande voorbeelden hebben me heel wat uren gekost om uit te vogelen.
Jouw vader gaf de klap op de tv.
Van mijn moeder leerde ik om niet naar de bekende weg te vragen.
Je geeft de antwoorden tenslotte zelf al.
Als end-user vond ik het altijd fijn als we na zo’n service-patch weer ff tv konden kijken..
Pascal,
haha, iedereen die software in een team gemaakt heeft kent deze zaken. En dat is ook zo leuk aan het vak; iemand kan prachtige code schrijven, maar een werkend systeem is meer dan prachtige code.
De redenen van de praktijk ervaring die je opsomt zijn legio, maar de meeste zijn denk ik wel terug te brengen op het werken in relatief eenvoudige omgevingen of in maatwerk omgevingen. Als je uitrolt naar plekken buiten jouw beheer (het boze internet, of erger nog, op de infrastructuur van klanten) dan komen dit soort zaken altijd veel sneller boven. En nogmaals, ik heb me aan al jouw punten al een keer schuldig gemaakt.
Daarnaast maak je wel eens iets om uit te proberen en moet dat snel af om een demo te kunnen geven. Dan is de klant ineens enthousiast en wordt Dev ineens productie en is er geen tijd om alle hard coded keuzen om te zetten naar duurzame code. Vanuit de klant logisch: Het werkt toch? Waarom moet ik dan extra tijd en geld investeren om het “duurzaam” te maken?
Klanten accepteren ook geen 50% test kosten. En het schrijven van code is in mijn optiek minder dan 50% van het opleveren van een duurzaam systeem. Ook unit testen en scenario’s maken kost nu eenmaal veel geld.
Zo herken je de vraag best; “Hoeveel tijd kost dat om te maken?” terwijl dat een hele foute vraag is. Want iedere functie (geen uitzonderingen) kost ook tijd in onderhoud en testen…. door de jaren heen.
Een voorbeeld; klant komt met een product keuze wizard. Hoeveel kost dat om te maken? Mijn antwoord; om het snel voor nu aan de praat te krijgen? 2500 euro. Om het duurzaam te maken? 25.000 euro. Klanten snappen dat niet en wordt er gekozen voor een goedkope variant aan de voorkant, vervolgens komen er wijzigingen uitbreidingen en kost de oplossing op termijn 50.000 euro en blijven ze afhankelijk van de ontwikkelaar omdat het niet generiek is opgezet.
Goede duurzame software is een vak, daar heb je ook veel amateurs die het voor minder doen….
“Instant gratification” is de root of all evil.
Dus herkenbaar en zoals altijd, leuk artikel!
@ Pascal,
Leuk stuk. Ondanks het niet mijn vakgebied is heb ik het stukje wel met veel plezier gelezen. Waar voor dank!
Heel herkenbaar, zou zomaar uit mijn directe omgeving kunnen komen. Dankjewel. #nietdeenige
Ik kan mijzelf overigens goed vinden in Henri’s quote: “Instant gratification” is the root of all evil.
Welke oorzaken ook ten grondslag lagen aan de symptomen die Pascal hierboven beschrijft, is dit een vaak terugkomende oorzaak.
Een gebrek om vooruit te kunnen denken, rekening houdend met ander factoren die van belang zijn in de fasen ná de eigen activiteiten. In mijn ervaring is dit vaak het gevolg van hoge werkdruk. Naar mijn idee zou een goed gecommuniceerde visie op het eindproduct, betrokkenheid van alle belanghebbende en daardoor doelgerichte aansturing door (technische) leidinggevenden een afdoende fail-safe moeten opleveren om de “Instant gratification” herkenbaar te maken en daarmee te voorkomen dat architectuur-, design- en implementatie keuzes hierop gebaseerd worden.
Zoals het artikel “Agile over common-sense methodology” van Jasper Boogers op LinkedIn aangeeft: “… Short-term thinking does not result from following short iterations and daily stand-ups. It is the result of a lack of vision, of not having an architecture to capture that vision, and of failing to share the vision with your teams. Understand that the vision is a direction; not a destination. …”
(Bron: https://www.linkedin.com/pulse/agile-over-common-sense-methodology-jasper-bogers)
@Dino … maar als de TV vervolgens een week uit de roulatie was omdat de monteur hem zo snel niet gerepareerd kreeg, was je dan als end-user ook nog blij?
Maar om even in de analogie te blijven:
Als monteur verdien ik hiermee een leuke boterham, maar liever besteed ik mijn tijd aan het ontwerpen / verbeteren van TV’s in plaats van ze te repareren.