Anex - kodestil

Jeg har en bestemt måde at kode på. Det er ikke fordi den er særlig indviklet – faktisk tværtimod. I mange tilfælde vil den virke direkte banal, og det er med fuldt overlæg. En klog mand sagde på et tidspunkt, at det er ~10 gange så svært at debugge kode, som det er at skrive den – hvilket betyder, at hvis jeg skrev kode lige på kanten af hvad jeg er dygtig nok til, så ville jeg ikke kunne debugge og dermed være ude af stand til at fixe bugs.

Ingen exceptions

Exceptions er i min verden forfærdelige til flow-kontrol og gør koden svær at læse. Hvis jeg kalder noget eksternt bliver det wrappet i en try-catch, der – og så returneres et fejlet retur-objekt, hvis en exception sker. Der er lige præcis en undtagelse – og det er en livrem og seler løsning i forbindelse med at Anex er multi-tenant (dvs. at der ligger mere end en virksomhed i databasen og på intet tidspunkt må data fra et regnskab være synligt i et andet). Hvis alle filtre og aspektorienterede koncepter fejler, så bliver der kastet en exception i det der svarer til DB-triggers i NHibernate (De kalder det event-listeners).

CQRS (Command-Query Segregation Principle)

Ja, ja – jeg er klar over, at inden jeg kan tælle til to, så vil der være mindst nitten CQRS-entusiaster der vil pege på alt det, der ikke er CQRS i koden. Lad os sige at CQRS er udgangspunktet. CQRS med særlige Tofty kendetegn (tm). Jeg har aldrig brudt mig om event stores (igen, ja jeg ved godt at en SQL-database teknisk set er en event store) – især omkring opdatering af data, efterhånden som koden udvikler sig, har jeg ikke set nogle gode løsninger på ‘gamle’ events.

Så jeg holder mig til det jeg kender: SQL- og dokumentdatabaser og nærmer mig CQRS så godt som jeg nu kan.

SOLID

Hvis du ikke kender dem, så er det din næste opgave. Jeg går af og til på kompromis med S’et (Single Responsibility Principle), men jeg tror mere det er et fortolkningsspørgsmål. Ét ansvar, ja tak, men hvor bredt definerer du et ansvar? Ansvaret for databasen? Ansvaret for opdateringer? Jeg går efter den pragmatiske løsning og lader være med at lave voldsomt store klasser.

Tests

Terminologi er svært – og ingen er enige om hvad vi kalder de forskellige niveauer af tests. Jeg fokuserer på de tests, der i min erfaring har fanget flest fejl: System- og integrationtests. Der hvor jeg har alt i spil, inklusive databaser, mine egne services, servicebussen osv. Med de værktøjer vi har til rådighed i dag med TestContainers, docker osv., så kan jeg ikke få øje på nogle undskyldninger for at undlade tests.

Jeg foretrækker black-box tests fremfor white-box tests og har en tendens til at fjerne unit-tests, efter de har drevet et design.

Database-/domænemodellen a.k.a. forretningslogikken

Med mindre at en parent class har brug for dens childs til validering, så vender mine dependencies altid omvendt. Dvs. at PartnerEmail (tænk: en glorificeret emailadresse) refererer Partner (tænk en juridisk person/enhed), mens Partner ikke har nogen referencer til PartnerEmail (altså, ingen collection af dem). Jeg har rigtig mange gode argumenter for det, men de er bedst illustreret ved et whiteboard og over en kop god te.