Afbeelding voor Hoe herken je goede code?

Hoe herken je goede code?

Goede code maakt het verschil. Tussen een prima website voor eindgebruikers en een project waar ook bouwers blij van worden. In deze blog geef ik vijf tips voor het herkennen van goede code.

Stel: je wilt een mooie nieuwe website hebben. Je hebt samen een ontwerp gemaakt van hoe hij eruit moet komen te zien en functioneel moet werken. Misschien heb je ook wat afspraken rond de technische vereisten gemaakt, bijvoorbeeld over hoe snel de site moet zijn. Het team van ontwikkelaars gaat deze plannen vervolgens realiseren door middel van code. En dan: als het maar werkt, toch?

Nou, niet helemaal… Als het goed is, zal je nieuwe website namelijk een hele tijd meegaan. Dat betekent dat hij soms onderhouden of bijgewerkt moet worden, misschien wel door een heel ander team van ontwikkelaars. Dan is het belangrijk dat die nieuwe mensen direct kunnen begrijpen wat de code doet.

Kijk eens aan mooi he

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

- Martin Fowler, Refactoring (1999)

Wat is code?

Eerst iets over code. Code is wat de ontwikkelaar schrijft om je webapplicatie, app of website te laten werken. Deze code is enerzijds door een apparaat te “lezen” en vertelt de computer of ander apparaat wat hij moet doen. Anderzijds — en nog veel belangrijker — moet deze code voor mensen leesbaar en begrijpelijk zijn. Het zijn immers mensen die de code schrijven en daarmee bepalen wat de computer moet doen. En het zijn eveneens mensen die de code vervolgens weer wijzigen en daar soms fouten uit halen. Goede code is daarom zowel door apparaten als mensen te begrijpen.

Code en programmeertalen

Die code is geschreven in een bepaalde programmeertaal. Bij Linku gebruiken we verschillende programmeertalen, libraries en frameworks om de projecten van onze opdrachtgevers te realiseren. Voor webapplicaties gebruiken we vaak JavaScript als programmeertaal in combinatie met Angular of React. Voor mobiele apps gebruiken we React Native of Ionic. Veel andere websites gaan uit van WordPress of Symfony, wat gebaseerd is op PHP. In deze blog praten we echter over kwaliteitsstandaarden voor code in het algemeen. Om dat mogelijk te maken, zullen we gebruik maken van voorbeelden met pseudocode. Pseudocode is code die niet écht werkt, maar door iedereen — inclusief niet-programmeurs — te begrijpen is.

Code: een voorbeeld

Veel code gaat uit van functies. Zo’n functie heeft een input, doet daar vervolgens iets mee (een operatie), en levert een output. Neem bijvoorbeeld de volgende functie:

gekookt_ei = koken(ei)

Hierbij is koken de functie, ei de input en gekookt_ei de output. Een functie kan ook meerdere input parameters hebben zoals hieronder:

zacht_gekookt_ei = koken(ei, 6_minuten)
hard_gekookt_ei = koken(ei, 10_minuten)

Hierbij vertellen we de functie niet alleen wat er gekookt moet worden (een ei), maar ook hoe lang. Dan zie je dat de output verschillend is.

Je kunt een functie ook met een andere functie combineren, bijvoorbeeld zo:

roerei = verhitten(roeren(ei))

Hier zeggen we dat het ei eerst geroerd moet worden en vervolgens verhit. Je ziet mogelijk al dat dit steeds complexer kan worden. Neem bijvoorbeeld de volgende functie:

y = B(C(D(a,b),E(c,F(b,d,e)),G(H(f),g,h)))

Daar kun je toch geen kaas van maken? Hoewel deze code mogelijk werkt, is er niets van te begrijpen. Hieronder vijf tips (en een bonustip) om je code begrijpelijker en beter te maken.

Code illustratie Bron: xkcd.com

Goede code in 5 tips

1. Gebruik beschrijvende namen

Je code wordt veel beter leesbaar als je beschrijvende namen gebruikt in plaats van abstracte constanten. Laten we dat in de bovenstaande formule eens proberen:

a = bakken(vullen(invetten(bakvorm,boter),kneden(bloem, roeren(boter,suiker,ei)),samenvoegen(snijden(appels),rozijnen,kaneel)))

Zo wordt het al iets duidelijker. Weet jij al waar a voor staat?

2. Splits je functies

Door de functies in je code te splitsen in losse functies met ieder hun eigen operaties wordt je code ook een stuk leesbaarder. Als je dit goed toepast, heeft iedere functie uiteindelijk één taak. Dit noemen ze ook wel het single responsibility principle.

ingevette_bakvorm = invetten(bakvorm, boter)
botermengsel = roeren(boter, suiker, ei)
deeg = kneden(bloem, botermengsel)
gesneden_appels = snijden(appels)
appelmengsel = samenvoegen(gesneden_appels, rozijnen, kaneel)
gevulde_bakvorm = vullen(ingevette_bakvorm, deeg, appelmengsel)
appeltaart = bakken(gevulde_bakvorm)

Het begint nu al bijna op een recept te lijken, toch?

Appeltaart

3. Voorkom herhaling

Een belangrijke leidraad bij het schrijven van goede code is het DRY-principe: ‘don’t repeat yourself’. Je code wordt vaak overzichtelijker (en efficiënter!) als je geen onnodige herhaling toepast. In ons voorbeeld zijn roeren en samenvoegen bijvoorbeeld vergelijkbare operaties. Hiervoor kunnen we een herbruikbare functie nemen: ‘mengen’:

botermengsel = mengen(boter, suiker, ei)
...
appelmengsel = mengen(gesneden_appels, rozijnen, kaneel)

Let hierbij op dat de leesbaarheid niet in gevaar komt. Soms proberen ontwikkelaars herhaling te voorkomen door steeds meer abstractie toe te voegen, waardoor de code ook moeilijker te begrijpen wordt. Dit is het paard achter de wagen spannen. De begrijpelijkheid van de code is het doel, het voorkomen van herhaling het middel. Zie ook het plaatje hieronder:

4. Maak je code voorspelbaar

Goede code is exact voorspelbaar en daarmee testbaar. Dat wil zeggen: als je precies doet wat de functie voorschrijft, moet je exact kunnen voorspellen wat de uitkomst is. De uitkomst is namelijk iedere keer hetzelfde. Dit gegeven wordt ook gebruikt wanneer we geautomatiseerde testen toevoegen aan je project, bijvoorbeeld unit tests. Deze controleren of de code zich gedraagt als voorspeld. Zo weten we zeker dat de applicatie nog goed werkt, ook nadat we wijzigingen in de code hebben aangebracht. Handig!

Ons voorbeeld kan in dit opzicht nog beter. Want hoe lang moeten we de taart bakken en op welke temperatuur? Door twee input parameters toe te voegen wordt onze ‘bakken’ functie voorspelbaar:

appeltaart = bakken(gevulde_bakvorm, 180_graden, 60_minuten)

5. Laat je code controleren

Zoals gezegd is goede code vooral leesbare code. En hoe weet je of je code begrijpelijk is? Door het aan een andere developer voor te leggen. Bij Linku werken we daarom structureel met code reviews. Voordat we iets aan het project wijzigen, laten we de nieuwe code door andere developers uit het team controleren. Die kijken of ze het duidelijk kunnen volgen en controleren of er geen foutjes in zitten. Zo weet je meteen of je code in de toekomst te begrijpen zal zijn, als andere mensen aan jouw project verder werken.

Bonustip: om je code goed te begrijpen, schijnt het goed te werken om deze hardop uit te leggen aan een rubber eendje. Al uitleggend zie je vanzelf hoe het werkt, of waar de fout zit.

Rubber duck debugging

De meerwaarde van goede code

Hopelijk heb ik je met deze voorbeelden kunnen overtuigen van de meerwaarde van goede code. Naast de bovengenoemde tips zijn er natuurlijk veel andere richtlijnen die de kwaliteit van je code kunnen verbeteren. Bij Linku worden developers continue bijgeschoold zodat ze de laatste standaarden en best-practices kunnen toepassen. Ook passen we handigheidjes toe, zoals de type-annotaties van Typescript zoals die ze in React en Angular gebruikt worden. Daarover in een volgend blog meer. Zo leveren we niet alleen een fantastisch uitziend en werkend product op, maar weet je ook zeker dat alles onder de motorkap optimaal en glashelder is.

Nieuwsbrief sfeerbeeld