Clean Code : Functies
De komende tijd zal ik proberen regelmatig hersenspinsels online te zetten in de vorm van een blogpost over zaken waar ik op het gebied van programmeren op dit moment mee bezig ben. In deze post een aantal eigenschappen en enige relevantie informatie over functies en het gebruik van functies in je programmeertaal (in de voorbeelden gebruik ik PHP).
Een aantal eigenschappen van een goede functie:
- de functie moet een relevante naam hebben
- een functie moet klein zijn
- een functie doet 1 ding (en dat doet hij goed)
- een functie heeft 1 niveau van abstractie
- Zijn beschrijvend (de naam verteld wat de functie doet, een functie met als naam cp() is bijvoorbeeld erg slecht leesbaar, als dezelfde functie copyFile() zou heten weet je direct wat de functie doet)
- Bevatten bijna altijd een werkwoord
- Moeten logisch zijn (een functie voor het inlezen van een XML bestand noem je bijvoorbeeld geen writeFile(), beter zou zijn readConfigFromXmlFile()
Functies moeten klein zijn
De functie in de afbeelding mist elk doel.
- Hij is niet leesbaar
- Bevat heel veel regels code
- Doet meer dan 1 ding
Kortom deze functie zou moeten worden opgedeeld in een (groot) aantal kleine functies. Dit zou de code meer leesbaar en een stuk overzichtelijker maken.
De originele functie bestond uit 130 regels code (op 3 abstractie niveau’s), de herschreven functie bevat 10 regels code op 1 abstractie niveau. Er zijn er 10 extra (nieuwe) functies bijgekomen in de betreffende class.
Slechts 1 ding doen
Functie dienen slechts één ding te doen. In de afbeelding hiernaast zien we een functie waarbinnen eigenlijk 3 acties plaatsvinden:
- we halen het banksaldo op
- we kijken of het saldo groter of gelijk is aan 0
- we retouneren het resultaat van een (render) functie
Het lijkt erop dat deze functie 3 dingen doet (3 acties uitvoert). Omdat al deze 3 acties op hetzelfde abstractie niveau zitten beschouw ik dit toch als een functie die slechts 1 ding doet.
Switch Statements in functie
Vrijwel elke programmeur maakt regelmatig gebruik van Switch statement zoals het statement hiernaast. In dit statement zien we dat we een functie “getAccountBalance” hebben. Deze maakt gebruik van de functie “getCurrency()” in het “account” object. Deze functie zorgt ervoor dat het banksaldo wordt teruggegeven in de juiste valuta. Dit switch statement kent een aantal nadelen:
- Deze functie (en bijbehorende switch statement) zal bij elke nieuwe currency worden aangepast
- Waarschijnlijk wordt een dergelijke functie op meer plekken gebruikt (immers we dienen het banksaldo ook in te stellen met een functie in de juiste valuta enz..)
De oplossing voor dit probleem is redelijk eenvoudig
- We stoppen dit switch statement weg (diep in de files) namelijk in een abstracte factory.
- De factory zal het switch statement gebruiken om een juiste instantie/object te maken van de afgeleide class
- De functies zullen worden gedefinieerd in een interface BankAccount
Onderstaand de voorbeeld code van een implementatie zoals die volgens mij beter en netter is.

