Als je wel eens naar een tiener, sportverslaggever of bedrijfsmanager hebt geluisterd, weet je dat er niet altijd een duidelijk verband is tussen woorden en betekenis. De computerwereld is een oase van rust in een wereld van anderszins krankzinnige communicatie. Niemand bewaart enen in een bitje als ze nullen bedoelen. Niemand typt x = 0 als ze eigenlijk x != 0 bedoelen. Logica is een stabiele haven in een wereld van vaagtaal en marketingblabla.

Maar helaas is zelfs in de informatica niet altijd alles even helder. Sommige ideeën, concepten of architecturen kunnen waardeloos zijn en toch de beste keus blijken voor jouw project. Misschien zijn ze goedkoper of sneller - of misschien is het gewoon te moeilijk om het goed te doen. met andere woorden: soms is slecht goed genoeg.

Er is soms ook goed nieuws als je wordt opgescheept met een slecht idee. Het is misschien niet de beste aanpak, maar dankzij goede extra effecten heeft het toch een meerwaarde. Als je een suboptimaal pad moet betreden richting de programmeerhel, kun je net zo goed gaan zoeken naar de juwelen die op dat pad verborgen liggen. Hier heb je zeven slechte programmeergewoontes die soms heel erg logisch zijn.

1. Quick and dirty

Er zijn maar weinig dingen die een project beter de nek om kunnen draaien dan slecht gedocumenteerde code. Zelfs als je bij elkaar gegooide stacks prima werken, wordt het een ramp om de code te onderhouden. Iedereen die de domme pech heeft om zich later om jouw dampende hoop bitjes te moeten bekommeren, zal je eeuwig blijven vervloeken.

Quick and dirty kan wel een plekje hebben. Het kan duur zijn om schone, goed doordachte code te schrijven. Ik werkte ooit met een ontwikkelmanager die iedereen apart nam en een lange lijst opsomde van manieren om de code op te schonen. De oude programmatuur draaide, maar het bedrijf joeg er twee maanden budget doorheen om zeker te maken dat de code er representatief uitzag. Soms vroeg onze manager om zes maanden budget daarvoor en kreeg ze dat ook. Want wie wil er nou lelijke code?

Niet iedereen heeft daar budget voor en er zijn maar weinig mensen die de financiers durven vragen om nog eens N-maanden aan ontwikkelkosten om de code op te schonen. Erger nog, schone code kan een hellend vlak zijn. De code die netjes is voor de ene programmeur, kan onnodig complex zijn voor de andere. Het opschonen betekent vaak nieuwe abstractieniveaus die duidelijk maken wat de code doet. Dat wordt snel simpelweg te veel informatie. Soms is quick and dirty beter dan complexe schone code die net zoveel pagina's heeft aan documentatie heeft als 'De ontdekking van de hemel'.

Lees ook: 34 hilarische opmerkingen in code

Iedereen die pagina op pagina van goed ontworpen code met meerdere lagen van abstracties heeft moeten doorworstelen, weet dat een simpele input met een simpele omschrijving in sommige gevallen veel beter is dan een meesterlijke programma dat een sterk staaltje computerewetenschap is. Stompzinnige, maar functionele code kan tien seconden kosten om te begrijpen; geavanceerde architecturen weken.

Het is niet zo dat goed werk een slechte zaak is, maar soms heb je de tijd en energie niet om alle slimmigheden uit te dokteren. Als tijd een factor is kan quick and dirty een groot voordeel zijn.

2. Slordige algoritmes

Soms loont het niet om slim te zijn. Dat zie je bijna nergens zo goed terug als het aankomt op goed onderzochte algoritmes met een sterk theoretisch fundament. Je herinnert je de lessen van school vast nog wel. Een slimme datastructuur verwerkt gegevens in tijd die relatief is aan de grootte van de data. Een slechte structuur wordt kwadratisch evenredig langzamer aan het aantal data-elementen. Die lessen zijn belangrijk: slechte algoritmes kunnen erg langzaam zijn.

Het probleem is dat slimme, theoretisch efficiënte algoritmes in de praktijk ook traag kunnen zijn. Ze vereisen vaak uitgebreide datastructuren vol met pointers en tussenwaardes - caches die RAM opvreten. Het kan maanden of zelfs jaren duren om dit goed te krijgen. Ja, op lange termijn draaien ze veel sneller. Maar in de woorden van John Maynard Keynes: "Op lange termijn zijn we allemaal dood."

Deel van het issue is dat de meeste theoretische modellen analyseren hoe algoritmes zich gedragen als de datasets groot worden. Zelfs in het tijdperk van big data, kunnen die datasets wel eens te klein blijven om praktisch winst te bemerken van die theoretische besparingen. In zulke gevallen is het misschien beter om een slordig algoritme in elkaar te zetten - zelfs als die potentieel trager is.

3. Aparte databaseserver

Snelheid is belangrijk als het gaat om software. Een paar milliseconden op het web kunnen het verschil betekenen tussen goed in de slappe was zitten en een totale flop. Om de snelheid tussen de lagen van software te verbeteren, zetten we de database op hetzelfde systeem dat de resultaten verwerkt voor de gebruiker. Je presentatielaag en de databaselaag communiceren soepel als er geen aparte machine aangesproken hoeft te worden.

Dit betaalt zich alleen niet altijd terug, vooral als een enkele machine niet efficiënt kan voorzien in de behoeftes van de presentatie- en databaselaag. Machines die erg goed zijn in het draaien van databases zijn vaak niet de machines die goed zijn in het draaien van de frontend. Om het nog ingewikkelder te maken: de verschillen zijn afhankelijk van het type en structuur van de databse die je gebruikt.

Meer RAM is altijd een goed idee, maar werkgeheugen is zelfs essentieel als het aankomt op indexen. Grote tabellen hebben veel meer RAM nodig dan een heleboel kleintjes. Als je van plan bent om veel JOINS uit te voeren, ben je wellicht beter af om de alles-in-een-trend te negeren en te gaan voor een aparte databaseserver.

Als je de database en de rest van de software bij elkaar gooit op één plek, kan die machine worden gedwongen om een manusje van alles te zijn, waardoor hij niets echt goed doet. Hij kan dan snel intern communiceren, maar kan niet specifieker worden afgesteld voor verschillende taken van je code.

4. Een CMS in plaats van eigen microservices

Een van de huidige trends is om de boel op te splitsen in microservices. In plaats van één portal voor al je data, bouw je tientallen of zelfs honderden webservices die specifieke query's verwerken om specifieke data te verzamelen. Daardoor kun je elke service los maken, debuggen en uitrollen - geweldig als je wijzigingen wilt doorvoeren zonder dat je een monolitische codebase hoeft te upgraden.

Een groot contentsysteem als WordPress of Drupal gebruiken om dit te bereiken is een andere manier om JSON- of XML-data te gebruiken. Dat lijkt aanvankelijk een slecht idee, omdat de extra complexiteit van een CMS de stack alleen maar kan vertragen. Maar een CMS-aanpak kan ook de ontwikkelsnelheid verhogen en debuggen verbeteren.

Het interne personeel dat het systeem moet beheren kan enorm geholpen zijn met dat 'contentbeheer'. Zelfs als gebruikers niet te maken krijgen met de CMS-lagen, kan het interne personeel voordeel behalen van de intelligentie erachter. De extra overhead kan een struikelblok zijn, maar dat is een relatief kleine in vergelijking van het toevoegen van meer elementen in de back-end.

5. Weergavecode en data in één

Een van de vuistregels van moderne ontwikkeling is dat je een project opdeelt in ten minste drie delen: dataopslag, beslissende logica en presentatie. Dit soort scheiding maakt het makkelijker om een deel los te herontwerpen, zonder dat je aan de andere hoeft te komen.

Er zijn nadelen aan dit idee, omdat het scheiden van weergave en de data zelf betekent dat de applicatie constant de data aan het verwerken is om in het huidige weergavesjabloon te passen. Dat wordt steeds herhaald als het sjabloon niet verandert.

De laatste tijd hebben architecten datatyperingen opnieuw bekeken om makkelijker code voor weergave te verwerken. De beweging naar JSON-datastructuren en NoSQL-databases is grotendeels veroorzaakt doordat mensen een formaat zochten dat makkelijker te verwerken was door een browser.

Nee, dat is inderdaad niet hetzelfde als data en display in elkaar schuiven, maar het brengt ze wel dichter bij elkaar. Meestal wordt een cache gebruikt om weergavecode en de benodigde data te combineren. Als data in een sjabloon wordt gedrukt, wordt het resultaat in de database opgeslagen om te hergebruiken wanneer dat nodig is.

6. Een suboptimaal fundament gebruiken

Niet zolang geleden betekende het kiezen van de 'verkeerde' architectuur of strategie voor je langetermijngroei de dood van je project. Vandaag de dag kun je van een matige keuze relatief eenvoudig bekomen, zolang het toevoegen van meer cloudresources om het probleem aan te pakken nog een werkbare oplossing is.

Als je serverstack traag is of de databases overstelpt raken, kun je tegenwoordig een tandje bijschakelen door meer machines in te huren. Als de massa verdwijnt, kun je makkelijk weer omlaag schalen. Nu machines luttele dubbeltjes per uur kosten, is het niet meer catastrofaal als je een architecturale inschattingsfout hebt gemaakt.

Niet elk probleem kun je oplossen door er dubbeltjes tegenaan te gooien. Sommige slechte beslissingen leiden tot exponentiële problemen als een bedrijf groeit. De ritmeter van de cloud tikt door, waardoor dit soort mislukkingen de portemonnee snel leeg kunnen trekken. Maar een zware database of een uitgebreide filter inzetten die twee keer zo traag is, is niet hetzelfde probleem als vroeger, zolang het probleem maar niet verergert.

De oplossing is om bottlenecks te vermijden in het cruciaalste, centrale deel van het ontwerp. Door de bewegende onderdelen zoveel mogelijk te scheiden van de kern, komen ze niet fundamenteel met elkaar in contact om betrokken te raken bij een dodelijke botsing. Zolang de kern van de architectuur daardoor niet in een file raakt, kunnen slechte beslissingen worden verholpen met betere hardware. Het is geen elegante oplossing, maar het is vaak effectief.

Neem Facebook, wat begon met PHP - een van de vroege tools voor webapplicaties - dat al een beetje verouderd voelde toen Facebook verscheen. De onaantrekkelijke issues zaten echter vooral programmeurs dwars; gebruikers merkten er niks van. Rare syntaxis en beperkte vaardigheden terzijde, de aanpak was prima.

Facebook heeft sindsdien PHP achter zich gelaten en creëerde de HHVM, een snellere versie die zelfs leidde tot het herschrijven van de PHP-core. Nu draait Facebook oude code een stuk sneller en gebruikers weten niet dat het bedrijf destijds koos voor een voor zijn doeleinden minder geschikt platform waarvan menig programmeur nog steeds met de ogen rolt.

Het is vaak goedkoper om een oplossing te kiezen die net goed genoeg is, dan een geavanceerde nieuwe oplossing. Het kan een fortuin kosten om de software te herontwerpen zodat het soepel en efficiënt draait. Een erg slimme programmeur kost een zescijferig jaarsalaris, maar daar koop je miljoenen serveruren voor bij Amazon. Het loont dus niet altijd om slim te zijn als hardware goedkoop en per uur te huren is.

7. Stoffige code in productie houden

Een team van managers betrok me ooit bij de ontwikkeling van een luxe, moderne webapplicatie met de nieuwste ideeën en nieuwste taal (toentertijd was dat Java). Het probleem was dat de oude mainframe praatte met oude monochrome terminals en dat was zoveel sneller dat iedereen die de nieuwe code gebruikte klaagde of we alsjeblieft terug konden naar jaren zestig-tech.

Een van de nieuwe Java-programmeurs vertelde gefrustreerd: "Het is niet eerlijk dat we worden vergeleken met de oude groene scherm-app. We doen veel meer." En met 'meer' doelde hij op luxe lettertypes, smaakvolle kleuren en vormen die pasten in aanpasbare vensters. Dezelfde data ging nog steeds geen en weer, maar de mensen die de telefoontjes aannamen herinnerden zich hoeveel sneller alles ging met die groene schermen met hun vaste lettertypes.

De nieuwste software is niet altijd een verbetering. Er is een reden dat hardwarebouwers altijd grappen dat software-ontwikkelaars bestaan om triljoenen regels nieuwe code te schrijven om ervoor te zorgen dat de nieuwe hardware net zo traag is als de oude. Anders zou er nooit behoefte zijn aan nieuwe hardware.

Sommige van de eerlijkste programmeurs praten op serieuze toon over issues als technische schuld en doorlopende refactoring. Ze spreken uit kennis en ervaring over de noodzaak om te investeren in het verversen van code. Maar de droom om met eens schone lei te beginnen en alles te herschrijven verandert bij tijd en wijle in een nachtmerrie.

Het blijft een moeilijke beslissing. Als de oude code buggy is of niet meer werkt, moet je wel herschrijven. Maar soms is het herschrijven van een app om hem actueel te houden een grove vergissing. Soms doe je juist een stap terug en heb je een hippe nieuwe architectuur in de recentste hippe taal, maar krijg je ook te maken met alle hippe nieuwe bugs.