Trots att Clean Code-vågen svept över utvecklarvärlden de senaste åren så förundras jag gång på gång över läsbarheten på den kod som jag dagligen måste brottas med. När jag läser kod vill jag att det ska vara som att läsa en serietidning. Det ska inte krävas någon större tankeverksamhet för att begripa vad koden gör och jag ska absolut inte behöva hålla olika objekts tillstånd eller dåligt namngivna variabler i huvudet. Tyvärr stöter jag ändå alltför ofta på kod som har fler gemensamma punkter med Kafka än med Bamse.
Här kommer därför några små tips i hopp om att göra kodvärlden lite vackrare och mycket enklare att förstå. Tanken är att tipsen utan större arbetsinsats ska gå att sätta igång med omedelbart. Det är inget revolutionerande och säkert inga nyheter för de flesta men bevisligen behöver de upprepas.
Tänk igenom din namnsättning
Använd beskrivande namn med vedertagen nomenklatur. Undvik att använda prefix och följ de namnstandards som finns. Ett variabelnamn bör reflektera vad variabeln står för och ett metodnamn bör beskriva vad metoden gör, inte hur den gör något. Ett klassnamn bör vara ett substantiv som beskriver klassens syfte.
Något som man ofta ser är slentrianmässig namngivning som inte ger någon extra information utöver klassens typ:
List list = new ArrayList();
Med ett mer genomtänkt namn blir allt så mycket tydligare (och självklart bör generics användas även om jag inte gör det i dessa exempel):
List userAccounts = new ArrayList();
Något annat som jag ofta ser är konstanter som namnges efter vad de innehåller istället för vad de representerar. Namnge konstanten DAYS_PER_WEEK istället för SEVEN, eller ännu hellre, använd en väl namngiven enum.
Checka inte in bortkommenterad kod
Med relativt jämna mellanrum så stöter jag av någon anledning på bortkommenterad kod. Jag har aldrig förstått syftet med det, vill man ha tillbaka koden så finns den i versionshanteringssystemet. Jag antar att tanken är att det ska vara lättare att gå tillbaka till gammal kod men väldigt snabbt försvinner även den möjligheten då koden runt omkring fortsätter att utvecklas samtidigt som den bortkommenterade koden inte underhålls.
Det enda som bortkommenterad kod tillför är att den skräpar ned koden och gör den svårare att läsa så personligen brukar jag radera den, omgående.
Se upp med kommentarer
Det här kanske är lite kontroversiellt för vissa men i de absolut flesta fallen finns det ingen anledning att skriva kommentarer i koden. Med väl namngivna variabler och metodnamn blir en kommentar bara redundant information som måste underhållas tillsammans med koden.
Jag vet inte hur många gånger som jag blivit lurad av att någon ändrat koden men samtidigt inte ändrat kommentaren.
Men, tänker du, mitt projekt är så komplext att vi måste skriva kommentarer för att koden ska gå att förstå. Jag vågar dock påstå att du med största sannolikhet har fel, själv brukar jag tänka att om koden är så komplex att jag måste skriva en kommentar för att den ska vara begriplig så är det förmodligen koden det är fel på. Därefter ser jag över namnsättningar och refaktoriserar koden så att den ska bli mer läsbar. Som minst går det alltid att ”gömma” komplexiteten i en väl namngiven metod eller klass så att ”huvudflödet” inte drabbas. På så vis är det bara den utvecklare som verkligen ska ändra eller behöver förstå den komplexa kodsnutten som behöver bry sig, övriga behöver endast konstatera vad metoden gör.
Nedanstående kodsnutt skulle förmodligen få de flesta utvecklare att stanna upp, åtminstone en sekund eller två. Sannolikt skulle kodsnutten också ackompanjeras med en kommentar:
int sum = 0.25 * 365 * user.getAccount().getTotal();
Bryter vi istället ut det komplexa till en egen metod och använder genomtänkta namn så blir koden så lätt att läsa att kommentarer är överflödiga. På köpet får vi dessutom en metod, calculateTax(), som är lätt att enhetstesta:
int tax = calculateTax(user.getAccount());
I andra fall är kommentarer nästan en förolämpning. Hur dum tror personen som skrev koden att jag är, egentligen?
// Set the users name
user.setName(userName);
Blanda dock inte ihop kommentarer med Javadoc. Som ett absolut minimum bör alla publika klasser och metoder dokumenteras med Javadoc.
Förtydliga komplexa if-satser
Även när det kommer till if-satser så blir koden ofta betydligt mer lättläst om man väljer att bryta ut eventuella komplexiteter i egna metoder. Exempelvis stötte jag på följande if-sats i ett av mina tidigare projekt:
if (( d != null && referer.indexOf(d) != -1) && ( a != null && referer.indexOf(a) != -1)) {
// Referer is this article (d and a match). Do not update
...
Detta hade varit ett ypperligt tillfälle bryta ut if-satsen till en metod istället och koden blir genast mycket lättare att förstå:
if (isArticleInvalid()) {
//Now is even the comment unnecessary
...
Deklarera variabler där de används
Ta för vana att deklarera variabler så nära där de används som möjligt och inom det scope som de används i.
Titta på nedanstående pseudokod:
int sum = 10;
if (isValid()) {
// kod som använder sum
}
// sum används inte mer
Det som görs ovan är att signalera till läsaren att sum används någonstans senare i koden. För att tydliggöra att sum endast används i if-satsen så borde variabeln deklareras däri.
Det händer ibland att jag stöter på kod från, gissningsvis, gamla C-rävar. Dessa har för vana att deklarera alla variabler högst upp i varje klass vilket tvingar läsaren att gå igenom en mängd kod för att se var variabeln används. Dessutom är det väldigt lätt att missa att variabeln ”petas” på mellan deklarationen och där det är tänkt att använda variabeln så snälla, försök att undvika alla gamla C-laster.
Se upp med argument till metoder
Komplexiteten i en funktion ökar för varje argument så ur det perspektivet är metoden som inte tar något argument perfekt. Den blir lättare att testa och sannolikt även lättare att begripa. Sträva därför alltid efter att ha så få argument som möjligt. Självklart måste man i vissa fall skicka med en variabel eller två men börjar det blir fler än så tycker jag att man ska ta det som en varningsklocka. Dels är koden sannolikt för komplex och dels så gör den förmodligen mer än en sak. I enstaka fall, till exempel vid komplicerade matematiska beräkningar, så kan det ändå vara motiverat med både fyra, fem och sex argument. Det är dock troligt att argumenten i dessa fall har ett så tätt samband att de borde grupperas ihop till en eller två egna klasser.
Något annat som jag ofta ser är att det skickas in ”flaggor” till metoder där metoden, beroende på om flaggan är sann eller falsk, gör två helt olika saker. Här blir koden mycket mer läsbar om det skulle vara två separata metoder istället så mitt tips är att helt undvika sådana flaggor.
Sammanfattningsvis, lägg hellre ned några minuter extra när du skriver din kod för att den ska bli lätt att läsa och lätt att förstå. Annars är det med största sannolikhet ändå du som sitter och kliar dig i huvudet om några veckor och inte har en aning om vad koden egentligen gör.