Onderhoudbaar programmeren maakt ontwikkelen goedkoper
10 tips om inzichtelijker code af te leveren
Om programmacodes op onderhoudbaarheid te kunnen vergelijken zocht SIG jarenlang in duizenden broncodes naar programmeergewoonten die het verschil maken tussen goed en slecht onderhoudbare code. Die eigenschappen zijn een-op-een te vertalen in richtlijnen om beter (we laten het woord onderhoudbaar maar even weg) te programmeren. De tien belangrijkste daarvan werkte Visser uit in een boek dat enkele maanden geleden bij O’Reilly verscheen: Building Maintainable Software. Hier zijn ze in een notendop:
1. Deel je code op in kleine eenheden
Splits componenten of subroutines die meer dan vijftien regels code bevatten op. Dat maakt de modules begrijpelijker, beter testbaar en vaak ook meer herbruikbaar.
2. Houd die eenheden eenvoudig
Beperk het aantal punten waarop het uitvoeringsverloop van het programma kan wisselen (‘branch points’) tot hooguit vier per module. Als er meer IF-statements (of daaraan functioneel verwante opdrachten) nodig zijn, splits de betreffende component of subroutine dan op. Dat maakt de modules begrijpelijker en daarmee ook makkelijker te testen en te veranderen.
3. Schrijf code eenmalig
Maak codepassages herbruikbaar door ze onder te brengen in aanroepbare subroutines, en niet door code te kopiëren. Duplicatie van code betekent verdubbeling van de inspanning die nodig is om de code te inspecteren en waar nodig aan te passen.
4. Houd de interfaces tussen modules beknopt
Zorg dat subroutines nooit meer dan vier parameters gebruiken. Als er meer variabelen van buiten de routine nodig zijn; verpak ze dan in een apart project. Subroutines die minder parameters hebben zijn makkelijker te begrijpen en beter herbruikbaar.
5. Houd zaken uit elkaar in afzonderlijke subroutines
Routines die meerdere functies vervullen werken verwarrend en leiden tot toename van het aantal afhankelijkheidsrelaties in de code. Geef alle deeltaken in het programma een afzonderlijke subroutine en verberg de complexiteit van elke taak achter een beknopte subroutine-interface. Dit vergroot de inzichtelijkheid van de code doordat het de onderlinge afhankelijkheden tussen de subroutines vermindert.
6. Beperk het aantal afhankelijkheden tussen architectuurcomponenten
Houd op het hoogste niveau van de functiepiramide (het componenten-niveau) de interactie tussen de codemodules beperkt. Doe dat door zo min mogelijke code op te nemen die kan worden aangeroepen vanuit andere componenten. Dit bevordert de aanpasbaarheid doordat onafhankelijke componenten afzonderlijk in onderhoud kunnen worden genomen.
7. Kies het aantal architectuurcomponenten juist
Houd het aantal componenten, op het hoogste niveau van de functiepiramide, ergens in de buurt van negen en houd de componenten ruwweg gelijk in omvang. Dat zorgt voor gemak bij het lokaliseren van code en betere mogelijkheden om code af te zonderen voor het uitvoeren van aanpassingen.
8. Houd de totale codebase klein
Houd de totale hoeveelheid code voor een project zo beperkt als mogelijk. Perk daartoe zo nodig de functionaliteit in. Ook splitsen in twee projecten kan een optie zijn. Kleinere projecten en kleinere teams zijn belangrijke succesfactoren in softwareontwikkeling.
9. Automatiseer het testen van modules
Doe dat door het schrijven van testroutines in een testframework. Dat loont omdat die testroutines ook weer van pas komen als de code moet worden aangepast, wat meestal eerder nodig is dan de ontwikkelaar op het moment van schrijven geneigd is aan te nemen.
10.Schrijf schone code
- Laat je niet verleiden tot quick fixes, maar pas de subroutine dusdanig aan dat aan z’n opbouw niet meer is te zien dat er iets in is aangepast: na de ingreep ziet de subroutine er elegant uit, alsof hij zojuist is opgesteld door een bekwame software-engineer.
- Schrijf leesbare code die nauwelijks ingebedde commentaarregels nodig heeft. Uitgebreide tekstuele toelichting duidt op een gebrek aan leesbaarheid van de code zelf.
- Neem geen code op in de commentaren. Dat werkt verwarrend en er is geen reden voor. Als je een stuk oude code niet durft weg te gooien, dan is een commentaarregel niet de plaats om het te bewaren. Als het goed is, is de oude code straks terug te zoeken via het versiebeheermechanisme van je developers workbench.
- Laat geen dode code achter. Dode code is code die nergens wordt aangeroepen of code die resultaten produceert die nergens worden gebruikt.
- Gebruik beschrijvende namen voor subroutines en variabelen, maar maak ze niet te lang.
- Gebruik geen ‘magische constanten’ oftewel nummers die uit de lucht komen vallen en waarvan een ander maar moet zien te begrijpen waarvoor ze staan.
- Handel uitzonderingen correct af. Denk niet ‘als het goed is doet dit zich toch niet voor’. Wat wie garandeert dat het goed is? En is het dat ook nog na een aanpassing elders in de code?