Stilguide
Vår stilguide er i bunn og grunn et lite utvalg fra Google Java Style Guide med noen få tillegg.
Generelt | |||||||||
---|---|---|---|---|---|---|---|---|---|
Koden må kompilere | Koden din må kompilere uten feil. Hvis nødvendig, kommenter ut kode slik at det du leverer kompilerer. | ||||||||
Koden må kjøre | Koden din må kjøre uten å krasje med en gang. Hvis koden din krasjer med en gang, har du tilgang til en feilmelding som hjelper deg å finne hva som er feil. Fiks feilen! Hvorvidt koden din er korrekt er egentlig et separat spørsmål; men så lenge koden krasjer med en gang er den hvertfall ikke korrekt. | ||||||||
Ikke gjenta deg selv | Følg prinsippet om DRY (don't repeat yourself). Hvis du skrive den samme (eller nesten den samme) koden to eller flere ganger, bør du sannsynligvis endre noe slik at du kun trenger å skrive den én gang i stedet. Bruk hjelpemetoder i stedet. | ||||||||
Modulær kode | Del opp koden din i pakker, klasser og metoder som representerer en logisk oppdeling av funksjonaliteten du trenger. Forsøk å begrense avhengighetene mellom de ulike klassene så mye som mulig. | ||||||||
Selvdokumenterende kode | Alle klasser, metoder og variabler skal ha selvforklarende navn. Det er bedre med et selvforklarende navn som er langt enn et uforståelig navn som er kort. Dette er spesielt viktig for metoder, klasser, og feltvariabler. | ||||||||
Gjør det enkelt | Følg prinsippet om KISS (keep it simple, stupid). Ikke ta hensyn til absolutt alle mulige fremtidige eventualiteter første gang du skriver en kodesnutt, men løs først og fremst problemet du har behov for å løse akkurat nå. | ||||||||
Javadoc | |||||||||
Javadoc for alt som er public og protected | Alt som er public eller protected (klasser, metoder, konstruktører, feltvariabler) skal ha en javadoc-kommentar som beskriver hva det og hvordan det skal brukes. Javadoc-kommentarerer begynner med /** og avsluttes med */ , og skrives like før definisjonen av klassen/metoden/variabelen. For eksempel:
Korte javadoc-kommentarer kan skrives på én linje
|
||||||||
Ikke kombiner javadoc og @Override |
Hvis en public metode er annotert med @Override, skal du likevel ikke skrive javadoc. La i stedet metoden implementeres i hehold til javadoc skrevet der metoden arves fra. | ||||||||
Beskriv returverdi | En javadoc-kommentar for en metode skal beskrive hva metoden returnerer. Kan inkludere et eksempel på input og output. | ||||||||
Beskriv sideeffekter | En javadoc-kommentar for en metode skal beskrive hvilke sideeffekter metoden har, og være tydelig på hvilket objekt som i så fall muteres. Bruk «this» for å referere til objektet metoden blir kalt på. | ||||||||
Beskriv oppførsel ved null-argumenter | En javadoc-kommentar for en metode skal beskrive hva metoden gjør dersom et argument er null, og hva metoden gjør dersom argumentene på andre måter ikke er gyldige. | ||||||||
Beskriv parametre med @param |
Dersom javadoc går over flere linjer, beskriv hvert enkelt parameter med @param. I disse tilfellene, beskriv også returverdien med @return. For eksempel:
|
||||||||
Beskriv kjente exceptions med @throws |
Beskriv excepitions du forutser kan oppstå, både deklarerte og ikke-deklarerte. For eksempel:
|
||||||||
Javadoc < 72 tegn | Ingen javadoc-linjer skal passere 72-tegn-grensen. Del heller opp kommentarer over flere linjer (unntak for lange internettadresser, som eventuelt kommer på en egen linje). | ||||||||
Kommentarer | |||||||||
Ikke undervis Java | Ikke bruk kommentarer for å forklare hva Java gjør. Anta at den som leser koden din kan Java allerede. For eksempel, ikke skriv kommentarer som dette:
|
||||||||
Unngå unødvendige kommentarer | Det er bedre med selvdokumenterende kode enn kommentarer. Benytt kommentarer kun dersom det ikke fremgår tydelig av metodenavn, javadocs og variabelnavn hva som skjer i metoden. | ||||||||
Korte kommentarer | Hvis du trenger kommentarer i koden din for å gjøre den forståelig, hold kommentarene korte og konsise. For eksempel, ikke skriv lange kommentarer som dette:
men skriv heller korte kommentarer som dette:
|
||||||||
Korrekte kommentarer | Sørg for at kommentarer er oppdatert til en hver tid, og beskriver koden presist og korrekt. Det er verre med ukorrekte kommentarer enn ingen kommentarer i det hele tatt. | ||||||||
Kommentarer < 80 tegn | Ingen kommentarlinjer skal passere 80-tegn-grensen. Del heller opp kommentarer over flere linjer (unntak for lange internettadresser, som eventuelt kommer på en egen linje). | ||||||||
Formatering | |||||||||
Innrykk på 2 mellomrom | Benytt 2 mellomrom for å lage innrykk i koden din. Ikke bruk tab-symbolet. Konfigurer din editor til å bruke 2 mellomrom, og benytt din editor sin funksjonalitet for å automatisk rykke inn linjer hvis du ser at koden ikke er rykket inn skikkelig.
Konfigurering:
For å automatisk lage innrykk i filen du jobber med:
Konfigurering:
For å automatisk lage innrykk i filen du jobber med:
|
||||||||
Kodelinjer < 80/100 tegn | Kodelinjer skal ideelt ikke passere grensen på 80 tegn per linje. Vi tillater likevel å bryte denne grensen av og til, men kun dersom det er maksimalt ett metodekall på linjen og det ikke umiddelbart lar seg gjøre å dele opp linjen med enkle grep. Ingen kodelinjer kan derimot være lengre enn 100 tegn. Unntaket er for lange internettadresser, i så fall lagres disse i en egen streng på en separat linje.
|
||||||||
Bruk mellomrom riktig |
Vi ser her på bruk av mellomrom som teknisk sett er frivillig, men hvor vi har retningslinjer som gjør koden vår penere å lese.
|
||||||||
Navngivning | |||||||||
Selvbeskrivende navn | Navn på klasser, metoder og variabler skal være selvbeskrivende. Ideelt sett bør navnet beskrive sin egen rolle såpass godt at det ikke er nødvendig å lese javdoc for å forstå hva metoden gjør eller hva variabelen inneholder. Jo mer eksponert navnet er, jo viktigere er det at navnet er selvbeskrivende. Derfor er det for eksempel enda viktigere med selvbeskrivende navn for feltvariabler enn for lokale variabler. |
||||||||
Korte navn | Navn på klasser, metoder og variabler skal være korte. Jo kortere navn, jo bedre; men det er likevel viktigst at navnet er selvbeskrivende. Hvis du må velge mellom et kort navn og et selvbeskrivende navn, velg det selvbeskrivende navnet. | ||||||||
Presise navn |
Navn på klasser, metoder og variabler skal være presise. For eksempel er Hvis dennne regelen fører til at navnet på metoden din blir uhåndterlig langt, kan det være et tegn på at metoden har for mange hensikter, og burde vært delt opp i hjelpemetoder. |
||||||||
Navn på klasser er UpperCamelCase | Navn på klasser og klasse-lignende ting som grensesnitt, enum, record, abstrakte klasser etc. skal begynne med stor bokstav, og ha en ny stor bokstav i stedet for mellomrom. Klassenavn skal normalt være substantiv (f. eks. Person, School, TetrisBoard), mens grensesnitt noen ganger kan være/begynne med adjektiv (f. eks. Runnable, ViewableModel, Controllable). | ||||||||
Navn på metoder og variabler er lowerCamelCase | Navn på metoder og variabler skal begynne med liten bokstav, og ha en ny stor bokstav i stedet for mellomrom. Variabler er vanligvis substantiv (f. eks. board, familyName, items), mens metoder vanligvis begynner med et verb (f. eks. insert, getAge, removeFullRows). Unntak er for boolske (retur-)verdier, da kan navnet på variabelen eller metoden gjerne være et ja/nei -spørsmål (for eksempel isAlive eller hasContent). | ||||||||
Navn på konstanter er UPPER_SNAKE_CASE | Navn på konstanter (uforanderlige feltvariabler som er static og final eller enum-objekter) skrives med store bokstaver og benytter underscore i stedet for mellomrom. | ||||||||
Navn på pakker er lowercase | Navn på pakker er kun lowercase uten underscore, og begynner vanligvis med reversert domene til eier av koden; for eksempel no.uib.inf101.myapp . |
||||||||
Kvalifisering med this |
Når vi kaller på instansmetoder eller bruker instansvariabler som tilhører objektet vi kjører i konteksten av, kvalifiserer vi navnet på metoden eller variabelen ved å bruke «this. » før navnet på instansmetoden/instansvariabelen. Dette er nyttig for ferske programmerere for å bli vant til at this eksisterer, det tydeliggjør for leseren at variabelen/metoden er en instansvariabel/metode og vi unngår samtidig at lokale variabler skygger for instansvariabler uten at vi mener det. |
||||||||
Kvalifisering med klassenavn | Når vi kaller på klassemetoder eller bruker klassevariabler/konstanter, kvalifiserer vi navnet på metoden eller variabelen ved å bruke «KlasseNavn. » før navnet på klassemetoden/klassevariabelen. Fordi klassenavn alltid begynne med stor bokstav (se over), kan vi på denne måten umiddelbart kjenne igjen at metoden/variabelen er statisk. |
||||||||
Kodestil | |||||||||
Korte metoder | Hver enkelt metode skal være kort og konsis, og være lett å lese. Dersom metoden innebærer flere sub-steg, skal disse være utskilt som hjelpemetoder. Det er nesten aldri hensiktsmessig med mer enn 20 linjer kode per metode (unntak for svært oversiktlige switch-uttrykk). | ||||||||
Unngå magiske verdier | En magisk verdi er en konkret verdi (for eksempel «15») som benyttes i koden uten å være angitt som en variabel med tilhørende selvbeskrivende navn. I stedet for å bruke magiske verdier kan du angi konstanter med selvbeskrivende navn og så benytte dem. For eksempel, ikke bruk den magiske verdien 15 slik som dette:
men opprett en konstant med selvbeskrivende navn i stedet :
Dersom denne samme verdien (15) brukes annet sted i koden også, skal kanskje de to verdien alltid være synkronisert. Da må de hentes fra samme sted; definer for eksempel verdien som en feltvariabel. Enten som en konstant klassevariabel, eller (ofte enda bedre) du kan bruke en instansvariabel slik at koden blir dynamisk og virker like bra for andre verdier enn 15 også. Verdier vi ikke regner som magiske er |
||||||||
Unngå statiske variabler | Klassevariable/statiske variabler hører ikke hjemme i et godt strukturert, modulært og testbart program. I hvert fall utrolig sjeldent. I INF101 er det ikke lov å bruke statiske variabler for noen andre formål enn konstanter. | ||||||||
Begrens skopet til variabler | Benytt det minste mulige skopet for en variabel. Ikke benytt feltvariabler hvis du klarer deg med en lokal variabel. | ||||||||
Bruk parenteser |
Bruk paranteser når du skriver kombinerte uttrykk. Ikke anta at den som leser koden din har memorisert java sin presedenstabell. Riktig:
Feil:
|
||||||||
Ikke bruk == med flyttall |
Når man regner med flyttall kan det oppstå avrundingsfeil som gjør at sammenligning med == feiler. Benytt almostEqual i stedet:
|
||||||||
Ikke bruk == med objekter |
For å sammenligne om to objekter a og b er like, ikke bruk a == b , men benytt Objects.equals(a, b) i stedet. Kun ved sammenligning mot null eller i sjeldne tilfeller hvor man faktisk ønsker å sammenligne referanser (og begrunner bruken godt med en kommentar) kan man benytte == for å sammenligne objekter.
|
||||||||
Benytt hjelpevariabler | Ved komplekse operasjoner og utregninger er det nyttig å mellomlagre delvise resultat i «hjelpevariabler.» Dette gjør koden lettere å lese, mer selvdokumenterende, og mye lettere å feilsøke med en debugger. | ||||||||
Små klasser kan være uforanderlige | Hvis objekter i en klasse representerer en begrenset mengde data (inneholder ikke store samlinger/lister av noe) må du vurdere om klassen burde være uforanderlig. | ||||||||
Variabler har abstrakte typer | Når du skal velge variabeltype, velg en type som er så høyt oppe i typehierarkiet som mulig, men så lavt som nødvendig. Det er for eksempel bedre om en variabel har typen |
||||||||
Innkapsling | |||||||||
Bruk strengeste tilgangsmodifikator | Som utgangspunkt bør du alltid bruke strengeste mulige tilgangsmodifikator som tillater deg å gjennomføre det du skal. | ||||||||
Instansvariabler er private | Alle instansvariabler skal være private. Hvis du trenger tilgang til dem utenfor klassen, bruk get og set-metoder. | ||||||||
Testing | |||||||||
TestFoo ligger i samme pakke som Foo |
Når man skriver JUnit-tester for en klasse Foo i pakken com.sample.myapp, skal klassen som tester Foo hete TestFoo og også ligge i pakken com.sample.myapp. Merk dog at testen skal ligge i test-mappen, ikke i main-mappen i maven-prosjektet. |
||||||||
Test public og protected metoder | Skriv tester for alle metoder som er public eller protected. Tester for metoder som er pakke-privat er valgfritt. Ikke skriv tester for private metoder (tester skal teste funksjonalitet, ikke implementasjonsdetaljer) | ||||||||
Test for likhet | Det er bedre å teste at en oppførsel gir et visst resultat enn å teste at det ikke gir et visst resultat (selv om det er ett riktig svar, kan det være mange gale svar). | ||||||||
Test hjørnetilfeller | Skriv tester for de spesielle tilfellene. Skriv tester der du bruker veldig små verdier, veldig store verdier, nullverdier, ulovlige verdier og annen oppførsel som bare oppstår sjelden ved normal bruk. |