Innlegg
9 retningslinjer for å lage uttrykksfulle navn
28. oktober 2019 • 6 min lesing

Navngiving er subjektivt og situasjonsavhengig, det er en kunst, og som med mest kunst oppdager vi mønstre. Jeg har lært mye gjennom å lese andres kode. I denne artikkelen har jeg samlet 9 retningslinjer jeg ønsket andre hadde fulgt når jeg leste koden deres.
Når en programvareingeniør åpner en klasse, bør hun vite, basert på navnene, klassens ansvarsområder. Ja, jeg vet at navngiving bare er én eike i hjulet, fysiske og logiske strukturer spiller også en betydelig rolle i å forstå koden, det samme gjør kompleksitet. I denne artikkelen fokuserer jeg bare på navngiving fordi jeg føler det har størst innvirkning på forståelsen av koden.
Ikke inkluder type med mindre det klargjør hensikten
En type kan være alt fra en programmeringstype (string, int, decimal) til en gruppering av ansvarsområder (Util, Helper, Validator, Event, osv.). Ofte er det en klassifisering som ikke uttrykker hensikt.
La oss se på et eksempel: Navnet StringHelper uttrykker ikke mye. En string er en systemtype, og Helper er vagt, StringHelper snakker mer til “hvordan” enn hensikten. Hvis vi i stedet endrer navnet til DisplayNameFormatter får vi et klarere bilde av hensikten. DisplayName er veldig spesifikt, og Formatter uttrykker utfall. Formatter kan være en type eller ikke, men det spiller ingen rolle, fordi det uttrykker hensikt.
Det er alltid unntak; for eksempel i ASP.Net MVC må kontrollere ende på “Controller” eller applikasjonen fungerer ikke. Ved bruk av paradigmer som Domain Driven Design (DDD) har navn som “Services,” “Repository,” “ValueType” og “Model” betydning i DDD og uttrykker ansvar.
For eksempel antyder UserRepository at brukerdata hentes og lagres til et datalager.
Unngå metaforer
Metaforer er kulturelle, og ingeniører fra andre kulturer forstår kanskje ikke hensikten.
Vanlige metaforer i USA:
- Beating a dead horse
- Chicken or the egg
- Elephant in the room
Vanlige metaforer på New Zealand:
- Spit the dummy
- Knackered
- Hard yakka
Bruk verb
Steve Yegge skrev et (veldig langt) blogginnlegg om å bruke verb fremfor substantiv.
Poenget hans er å bruke verb, applikasjoner er sammensatt av substantiv, men substantiv gjør ikke ting. Systemer er ubrukelige med bare substantiv, uttrykk i stedet handling i navn på metoder.
For eksempel uttrykker UserAuthentication*(substantiv).AuthenticateUser(handling/verb)* handlingen med å verifisere en brukers legitimasjon.
Vær beskrivende
Vær beskrivende, jo mer detalj, desto bedre — uttrykk ansvaret i navnet.
Spør deg selv, hva er den ene tingen denne klassen eller funksjonen gjør godt?
Hvis du har vanskeligheter med å finne et navn, kan klassen eller funksjonen ha mer enn ett ansvarsområde og dermed bryte Single Responsibility Principle.
Ikke støtt deg på kommentarer for hensikt
Kommentarer er en flott måte å gi ekstra kontekst til koden på, men ikke støtt deg på kommentarer. Navnene på klasser og metoder bør stå på egne ben.
I Refactoring: Improving the Design of Existing Code av Martin Fowler, Kent Beck, John Brant, William Opdyke, og Don Roberts:
… kommentarer brukes ofte som deodorant. Det er overraskende hvor ofte du ser på tett kommentert kode og legger merke til at kommentarene er der fordi koden er dårlig.
Et annet fantastisk sitat fra “In Refactoring” forfatterne:
Når du føler behov for å skrive en kommentar, prøv først å refaktorere koden slik at enhver kommentar blir overflødig. Side 88
Mange ganger når koden refaktoreres og kapsles inn i en metode, vil du finne andre steder hvor det er mulig å utnytte den nye metoden, steder du aldri forventet å bruke den nye metoden.
Noen ganger når man kaller en metode trenger forbrukeren å vite noe spesielt om metoden, hvis den spesialiteten er en del av navnet, trenger ikke forbrukeren å gjennomgå kildekoden.
Her er et eksempel på å inkorporere en kommentar i et navn.
Med kommentarer:
// without tracking
var user = GetUserByUserId(userId);
Refaktorert til å inkludere kommentaren i metodenavnet:
var userWithOutTracking = GetUserByUserIdWithoutTracking(userId);
Andre ingeniører vet nå at denne metoden ikke har sporing før de trenger å enten lese kildekoden eller finne kommentaren.
Kommentarer bør være din siste forsvarslinje når mulig, støtt deg på andre måter å uttrykke hensikt inkludert bruk av fysisk og logisk struktur og navn for å formidle hensikt.
Avstå fra å bruke navn med tvetydig betydning
Unngå navn med tvetydige betydninger. Betydningen av tvetydige navn endres fra prosjekt til prosjekt, noe som gjør det vanskeligere for en ny ingeniør å forstå hensikten.
Her er en liste over vanlige tvetydige navn:
- Helper
- Input
- Item
- Logic
- Manager
- Minder
- Moniker
- Nanny
- Overseer
- Processor
- Shepherd
- Supervisor
- Thingy
- Utility
- Widget
Bruk samme språk som forretningsdomenet
Bruk samme terminologi i koden som i forretningsdomenet. Dette lar ingeniører og fageksperter (SME) enkelt kommunisere ideer fordi de deler samme vokabular. Når det ikke er et delt vokabular skjer oversettelse som uunngåelig fører til misforståelser.
I ett prosjekt jeg jobbet på, begynte virksomheten med “Pupil” og byttet deretter til “Student.” Programvareingeniørene oppdaterte aldri programvaren for å reflektere endringen i terminologi. Da nye ingeniører ble med i prosjektet trodde de fleste at Pupil og Student var forskjellige konsepter.
Bruk bransjespråk
Når mulig, bruk terminologi som har betydning på tvers av programvareindustrien.
De fleste programvareingeniører, når de ser noe navngitt “factory,” tenker umiddelbart på factory-mønsteret.
Bruk av eksisterende applikasjonsparadigmer som “Clean Architecture” og “Domain Driven Design” letter idédeling og skaper et felles språk for ingeniører å kommunisere ideer seg imellom.
Den verst mulige navngivingen er å kapre industriomfattende terminologi og gi den en annen betydning.
Når du navngir boolske verdier…
Boolske navn bør alltid være et svar på et spørsmål med verdien enten sann eller usann.
For eksempel, isUserAuthenticated, svaret er enten ja (true) eller nei (false)
Bruk ord som:
- Has
- Does
- Is
- Can
Unngå negerte navn, for eksempel:
Et negert variabelnavn:
var IsNotDeleted = true; // dette er forvirrende
if(!IsNotDeleted) { // det blir enda mer forvirrende når verdien negeres
//Do magic
}
Uten negert variabelnavn:
var IsDeleted = true; // dette er forvirrende
if(!IsDeleted) {
//Do magic
}
Til slutt
Å velge uttrykksfulle navn er avgjørende for å kommunisere hensikt, design og domenekunnskap til neste ingeniør. Ofte jobber vi med kode for å fikse feil eller inkorporere nye funksjoner, og vi kompilerer kontinuerlig kode i hodet vårt for å prøve å forstå hvordan det fungerer. Navngiving gir oss hint om hva den forrige ingeniøren tenkte, uten denne kommunikasjonen mellom tidligere og fremtidige ingeniører hemmer vi oss selv i veksten av applikasjonen. Potensielt dømmer vi prosjektet til fiasko.
Forfatter: Chuck Conway spesialiserer seg på programvareutvikling og Generativ AI. Koble til ham på sosiale medier: X (@chuckconway) eller besøk ham på YouTube.