Tag clean code

Imperatieve Options?

Ik gebruik Options graag, ze voorkomen een hoop foutmeldingen. Maar, belangrijker nog, ze maken mijn code expressiever en eleganter. Of liever: ze hebben de potentie dat te doen. Laatst kwam ik tijdens een codereview een functie tegen, waarop mijn primaire reactie was: dit moet anders. – Maar waarom?

Immutability en het Single-Responsibility Principe

Het correct – en dus volledig – instantiëren van een object is één verantwoordelijkheid. Het geïnstantieerde object gebruiken is een andere. Wie beide met elkaar vermengt, schrijft onnodig complexe code. Dat is waarom we er naar moeten streven onze objecten nooit aan te willen passen.

Codefluisteren

Een goede codefluisteraar kan in een stuk code werken en hoort dan – aanvankelijk zachtjes, maar met ervaring steeds duidelijker – plots een probleem. Het probleem is niet: de code werkt niet. Het probleem is: ik als ontwikkelaar ben nu harder aan het werk dan de code.

Waar doe je het voor?

Een luie programmeur grijpt alles aan om zijn eigen werk makkelijker te maken (met uitzondering van het besparen op kwaliteit - daar is een andere term voor: een slechte programmeur). En makkelijker maken betekent meestal: automatiseren. Want waarom zou je zelf het werk doen, als een machine het ook voor je kan doen?

Over de volgorde van je unit tests

Maakt het uit in welke volgorde je unit tests staan? - Nee. Tests slechts een middel om de werking van het systeem te valideren. Het maakt niet uit in welke volgorde de tests worden afgetrapt, als ze maar allemaal slagen. (Of liever: als ze maar op het juiste moment falen.) Dat is een mogelijk antwoord. - In een praatje van Kevlin Henney vond ik een ander antwoord.

Identifiers zijn ook objecten

Het oneigenlijk gebruik van “primitieve” types voor iets wat eigenlijk op een domeinniveau gedefinieerd hoort te worden, wordt primitive obsession genoemd. Het gebruik van een ingebouwd type voor een Id, is een specifieke instantie daarvan. De oplossing is: gebruik een door jou (of liever: jouw team) gedefinieerd object om het Id mee weer te geven.

Tests als ontwerpmiddel

Tests zijn een ontwerpmiddel, een design tool. Ze fungeren als indicator voor de kwaliteit van het ontwerp van je code. De vuistregel is even eenvoudig als zag-het-niet-want-het-stond-recht-voor-mijn-neus-vanzelfsprekend: Is het moeilijk om er een test voor te schrijven? Dan deugt het ontwerp niet!

Tests als vangnet

Tests zijn een vangnet. Elke keer dat je code aanraakt - en dat doe je continu -, dan speel je een balanceeract. Als je code blijft functioneren zoals bedoeld, blijf je op het koord. Zo niet, dan val je. En als je valt, heb je een keus: te pletter vallen, of opgevangen worden door een vangnet. Tests zijn je vangnet, je afgrond is - ontevreden ontwikkelaars, stakeholders, eindgebruikers.

Tests als documentatie

Tests zijn een vorm van documentatie. Ze leggen vast hoe een deel van je codebase zich hoort te gedragen. Maar ook: hoe je dat deel van de codebase gebruikt - wat je nodig hebt om het system under test te instantiëren, het gedrag van z’n methods etc.. Wie de tests leest, weet hoe de code gebruikt dient te worden. - Althans, dat is de ideale wereld.

Test-driven development is een ontwerpdiscipline

Een collega benaderde me laatst met een vraag over een stuk code. Hij was bezig met het implementeren van een feature om een toets met afbeeldingen om te zetten naar een PDF-representatie ervan. Zijn vraag was: hoe kom ik aan die afbeelding? Of liever: waar kom ik aan die afbeelding? Zijn eerste ingeving was om via dependency injection de relevante repository mee te geven aan de ImagePdfGenerator. - Het is een klassiek geval van het verknopen van het ophalen van data en het manipuleren ervan. Ik bleef wel met een knagend gevoel achter: hoe makkelijk blijkt het om dankzij een DI-container de verantwoordelijkheden van classes te verwateren - en wat moeten we daarmee?