We kennen allemaal wel projecten die met der tijd steeds minder onderhoudbaar worden. De ontwikkeling van nieuwe features gaat slomer, er wordt naar code gerefereerd als legacy en de onboarding van nieuwe mensen gaat moeizaam. Maar hoe heeft het zo ver kunnen komen, of beter, hoe voorkomen we dit? Leesbare code is je redding.
Één van de grootste oorzaken van bovengenoemde problemen is een berg aan code. Code die moeilijk te lezen en te volgen is voor de ontwikkelaars. Het is daarom belangrijk om focus te houden op begrijpbare en leesbare code. Idealiter zou elke willekeurige developer in een dag aan de slag moeten kunnen op een project. Helaas ligt de werkelijkheid hier vaak ver van af. Goed leesbare code maakt je code niet alleen toegankelijker, maar ook beter te onderhouden. Code wordt nu eenmaal meer gelezen dan geschreven. Net als dit verhaal heb ik het één keer geschreven, maar het wordt al minstens één keer meer gelezen.
Laten we het schrijven van code vergelijken met onze normale schrijftaal. Om een goed verhaal te schrijven moeten we:
- gebruikelijke woorden gebruiken,
- ons aan de regels houden van de grammatica en
- een logische volgorde voor onze zinnen en alinea’s gebruiken.
Ik zou in dit blogpost allerlei oud Nederlandse, Latijnse of Franse leenwoorden kunnen gebruiken, maar daar wordt de tekst niet duidelijker door. Ook wordt het niet duidelijker als ik alle nederlandse grammatica negeer, of deze blogpost begin bij het midden.
Dit zijn mijn vier vuistregels
1. Doelgroep
Allereerst de gouden tip, schrijf code niet voor jezelf, of voor de functionaliteit. Maar schrijf code om gelezen te worden door een ander. Veel teksten (zoals deze) beginnen met de realisatie “voor wie schrijf ik dit”, dit is niet anders voor programma’s. Bedenk je wie je code het meeste leest, of nog beter, wie je wilt dat je code het meeste leest. Zorg dat de code aansluit bij je doelgroep, gebruik voor die doelgroep bekende termen en conventies. Voorbeelden van doelgroepen kunnen zijn; je collega’s, je toekomstige collega’s of open source contributors.
2. Woordgebruik
In programmeer land is het niet veel anders dan in de tekst-schrijf wereld, alleen onze invulling is iets anders. De plekken waar je woorden vrij kunt gebruiken zijn iets gelimiteerder, zoals bij de naamgeving van variabele, functies modules, bestanden en mappen. Het is daarom zaak om die momenten met beide handen aan te grijpen en zo duidelijk mogelijke taal daarin te verwerken.
Gebruik bekende termen, het liefst van je domein model. Dit is herkenbaar voor de meesten binnen het project. Het is nog beter om deze termen en het domein te documenteren in iets als een domeinmodel. Dit mag een kleine schets op de muur zijn, zolang iedereen het maar eens is over de terminologie.
Wees ook consistent met de naamgeving. Een gebruiker op de ene plek een ‘person’ noemen en op de andere een ‘user’, terwijl je het over hetzelfde object hebt, is veelal verwarrend.
Ook een veel voorkomende valkuil: afkortingen. Doe het niet, gebruik ze niet. Deze afkortingen moet men allemaal leren en dienen geen ander doel dan je code inkorten. En waarom? Bijna iedereen heeft HD schermen of meer, met een regel lengte van minimaal 120 karakters. In deze 120 karakters is genoeg ruimte voor een duidelijke variabele naam zonder afkortingen. Kortom; wees niet bang voor lange variabele namen en functienamen. Je schrijft de code maar één keer, maar het leest zo veel duidelijker dan afkortingen zonder context.
3. Grammatica
Maar wat is grammatica in programmeer land? In veel programmeertalen staat de syntax vast, dit zouden we de grammatica kunnen noemen. Ware het niet dat hier weinig “afspraken” en interpretatie in zitten, terwijl dit wel zo is in taalgebruik. Met de grammatica in programmeer termen bedoel ik juist de afspraken die je binnen je project maakt over code. Van codestyling tot conventies. Denk hierbij aan afspraken zoals welke functionaliteiten van een taal er niet gebruikt dienen te worden, of juist wel. Maar ook hoe bestanden en eenheden gestructureerd dienen te worden. Deze afspraken vormen de grammatica van je project. Consistentie is hier ook weer erg belangrijk, hoe consistent dit is, hoe minder snel nieuwe mensen het “verkeerd” afkijken.
Het is dan ook belangrijk dat deze afspraken goed gedocumenteerd zijn, of nog beter, verplicht gecontroleerd worden door tooling zoals linters. Wat hierbij enorm helpt is om bestaande conventies te gebruiken. Dit documenteert en controleert vele malen sneller dan dit allemaal te moeten uitschrijven. Een voorbeeld is de AirBnB typescript eslint regels voor codestyling of Atomic design en Layered design voor programma structuring.
4. Zins opbouw
Als laatste de zins opbouw. Een logische volgorde van je programma hanteren is één ding. Maar er is een veel belangrijker aspect, wat we ook in de Nederlandse taal kennen en wat heel gauw, heel vervelend wordt: referenties. Je kent ze wel, de verhalen waar je begint met 2 namen, en daarna 5 pagina’s aan hij zei, en zij zei. Met 2 onderwerpen is dit nog te volgen, maar ideaal is anders. Net als in taal, wordt dit snel lastig te volgen in programma’s. Sterker nog, in de programmatuur gebeurd het wel eens dat je een referentie naar een referentie naar een referentie hebt. En als je pech hebt, verandert de betekenis van één van die referenties tijdens de uitvoering van je programma. Gelukkig heb ik hier wat tips voor.
- Probeer referenties te limiteren, of anders gezegd, verklein je scope (alle variabele die direct of indirect bereikbaar zijn) zo veel mogelijk. Daarom is in OOP talen het gebruik van `private` attribute zo gebruikelijk, net als je code opsplitsen in kleinere delen. Hiermee verklein je de scope op elk moment in je code. Ook zijn functies waarbij het resultaat puur afhankelijk is van de invoer argumenten (ook wel pure functions genoemd) een erg goede manier om je code beter leesbaarder te maken.
- Daarnaast is het aanpassen van referenties ook erg lastig te volgen. Net als woorden die afhankelijk van de context 2 betekenissen hebben, is vaak begrijpelijker om zo veel mogelijk woorden te gebruiken met een eenduidige betekenis. In de programmatuur heet dit concept ‘Immutability’ of het onvermogen tot aanpassen. Dit voorkomt veel hoofdpijn debug sessies in spaghetti code, waarbij er gezocht wordt naar een speld in een hooiberg situaties “waarom wordt dit object op enig moment veranderd?”.
Wil jij meer leren over leesbare code? Houdt ons vooral in de gaten op social media. Wellicht praat ik of één van mijn collega’s binnenkort op een meetup in de buurt. Of kijk eens op onze vacature pagina en leer in de praktijk meer! Zien hoe blij onze klanten worden van opgeschoonde code? Check dan deze case van Foleon.