Lyhyt yhteenveto Java-koodauksen parhaista käytännöistä

perustuu Oracle, Google, Twitter ja Spring Framework -standardien koodausstandardeihin

Tämän artikkelin tarkoituksena on antaa sinulle nopea yhteenveto tekemästä, eikä se siis toisin sanoen suosii ja välttää tekniikan jättiläisten, kuten Oracle, Google, Twitter ja Spring Framework, koodausstandardien perusteella.

Saatat olla tai olla eri mieltä joistain täällä esitetyistä parhaista käytännöistä, ja se on ehdottomasti hieno, kunhan on olemassa jokin koodausstandardi.

Miksi koodata standardeja? On monia hyviä syitä, jos käytät Googlea, ja annan sinulle seuraavan kuvan

Koodistandardidokumentti voi olla pitkä ja tylsä. Tämä artikkeli kirsikka poimii bittiä ja kappaleita Googlen, Oraclen, Twitterin ja Kevään koodaussopimuksista, ja sen tarkoituksena on tarjota sinulle helppo seurata ja vähemmän tylsää käytäntöjen kokoelma, jotta koodisi on helppo lukea ja ylläpitää.

Melkein aina liität tiimejä, jotka työskentelevät olemassa olevien ohjelmistojen parissa, ja on melko hyvät mahdollisuudet, että suurin osa kirjoittajista on lähtenyt tai siirtynyt erilaisiin projekteihin, jättäen sinut luopumaan koodiosista, jotka saavat sinut kyseenalaistamaan ihmiskunnan.

Harkitaan parhaita käytäntöjä erilaisista koodausstandardeista.

Java-lähdetiedosto

Seuraavia pidetään parhaina käytänteinä Java-lähdetiedostojen suhteen:

  • Lähteen tiedoston pituus on alle 2 000 riviä koodia
  • Lähdekortti on järjestetty dokumentaatiokommentin, paketti-ilmoituksen, jota seuraa luokkakommentin kanssa, tuo ryhmitetty (staattinen viimeinen), luokan / käyttöliittymän allekirjoitus ja niin edelleen, kuten alla on esitetty
paketti esimerkki.malli;
/ **
 * Kehittäjien tulee lukea toteutusvapaa näkökulma
 * joilla ei välttämättä ole lähdekoodia käsillä
 *
 * @author x, y, z
 * @Päivämäärä
 * @versio
 * @ tekijänoikeudet
 *
 * /
tuo com.example.util.FileUtil;
/ *
 * Valinnainen luokkakohtainen kommentti
 *
 * /
julkinen luokka SomeClass {
  // Staattiset muuttujat näkyvyyden järjestyksessä
  julkinen staattinen lopullinen kokonaisluku PUBLIC_COUNT = 1;
  staattinen lopullinen kokonaisluku PROTECTED_COUNT = 1;
  yksityinen staattinen lopullinen kokonaisluku PRIVATE_COUNT = 1;
  // Esimerkki muuttujat näkyvyyden järjestyksessä
  julkinen kielen nimi;
  Merkkijono postinumero;
  yksityinen merkkijono-osoite;
  // Rakentaja ja ylikuormitettu peräkkäisessä järjestyksessä
  julkinen SomeClass () {}
  julkinen SomeClass (merkkijono) {
    tämä.nimi = nimi;
  }
  // Menetelmät
  public String doSomethingUseful () {
    palauta "Jotain hyödyllistä";
  }
  // getters, setter, equals, hashCode ja toString lopussa
}

nimeäminen

Luokka- ja käyttöliittymänimet ovat CamelCase, ja on suositeltavaa käyttää koko sanaa ja välttää lyhenteitä / lyhenteitä. Esimerkiksi luokka Rasteri tai luokka ImageSprite

  • Paketti - nimet com.deepspace yli com.deepSpace tai com.deep_space
  • Tiedostonimet ovat CamelCase ja päättyvät .java-luokkaan. Tiedostoa kohti on yksi julkinen luokka, ja jokaisessa tiedostossaan on ylin taso
  • Menetelmä - nimien tulee olla verbejä sekoitettuna isoilla kirjaimilla, esimerkiksi run (); tai runFast ();
  • Vakiot - tulee olla iso kirjain, jossa ”_” erottaa jokaisen sanan, esimerkiksi int MIN_WIDTH = 44; ja int MAX_WIDTH = 99;
  • Muuttuja - nimi, joka kertoo ohjelman lukijalle, mitä muuttuja edustaa, ts. Jos tallennat testiluokkaa, valitse sitten luokka vs var1. Pidä muuttujien nimet lyhyinä, jotta metatietoja ei sisällytetä.
// Prefer () - muuttujien nimet ovat lyhyitä ja kuvaa, mitä ne tallentavat
int schoolId;
int [] suodatettuSchoolIds;
int [] uniqueSchooldIds;
Kartta  usersById;
Merkkijono arvo;
// Vältä (x) - Liian yksityiskohtainen muuttujien nimeäminen
int schoolIdentificationNumber;
int [] userProvidedSchoolIds;
int [] schoolIdsAfterRemovingDuplicates;
Kartta  idToUserMap;
Merkkijono arvoString;

Muista - muuttujan nimen tulisi olla lyhyt ja kertoa lukijalle helposti, mitä arvoa se edustaa. Käytä arviointiasi.

Suosittele ja vältä

Muotoilu ja sisennys merkitsevät koodin järjestämistä helpon lukemisen helpottamiseksi, ja se sisältää välilyönnit, rivin pituuden, kääreet ja tauot ja niin edelleen

  • Kaltevuus - Käytä 2 tai 4 välilyöntiä ja pysy johdonmukaisena
  • Rivin pituus - Enintään 70 - 120 merkkiä riippuen luettavuuteen. On tärkeää poistaa vaakavierityksen ja rivinvaihdon tarve pilkun ja operaattorin jälkeen.

Menetelmät - Tässä on luettelo parhaista käytännöistä

// Mieluummin () Rivinvaihdot ovat mielivaltaisia ​​ja katkeavat pilkun jälkeen.
Merkkijono downloadAnInternet (Internet-Internet, Putket,
    Blogosfääriblogit, määrä  kaistanleveys) {
  tubes.download (Internet);
}
// Vältä (x) Menetelmää on vaikea hajauttaa menetelmän runkoon
Merkkijono downloadAnInternet (Internet-Internet, Putket,
    Blogosfääriblogit, määrä  kaistanleveys) {
    tubes.download (Internet);
}
// Mieluummin () Lisää 8 (kaksinkertainen 2 tai 4) välilyöntiä syvälle sisennyslle
yksityinen staattinen synkronoitu horkingLongMethodName (int anArg,
        Kohde toinenArg, merkkijono vieläAnotherArg,
        Object andStillAnother) {
  ...
}
// Mieluummin () Helppo skannaus ja ylimääräinen saraketila.
public String downloadAnInternet (
    Internet Internet,
    Putket putket,
    Blogosfäärin blogeja,
    Määrä  kaistanleveys) {
  tubes.download (Internet);
  ...
}
Yksikkötesti olisi saanut tuon

Jos tarkastuksia - IMO: n kirjoittamalla hyvin muotoiltu koodi on helppo havaita kirjoitusvirheitä ja virheitä kirjoittajalle ja koodin tarkistajille, katso alla:

// Vältä (x) Älä jätä pois {}
jos (ehto)
  lausuma;
// Vältä (x)
jos (x <0) negatiivinen (x);
// Vältä (x)
if (a == b && c == d) {
...
}
// Suosittele ()
if ((a == b) && (c == d)) {
...
}
// Suosittele ()
if (ehto) {
  lausumat;
} muuta jos (ehto) {
  lausumat;
} muuta jos (ehto) {
  lausumat;
}
// Vältä (x)
if ((ehto1 && ehto2)
    || (ehto3 & kunnossa4)
    ||! (ehto5 & ehto6)) {// BAD WRAPS
    doSomethingAboutIt (); // TEE TÄMÄ RIVI HELPOSTI MISSÄ
}
// Suosittele ()
if ((ehto1 && ehto2)
        || (ehto3 & kunnossa4)
        ||! (ehto5 & ehto6)) {
    doSomethingAboutIt ();
}

Kolmiosainen operaattori - ja alla suositellaan käytäntöjä

alfa = (aLongBooleanExpression)? beeta: gamma;
alfa = (aLongBooleanExpression)? beeta
        : gamma;
alfa = (aLongBooleanExpression)
        ? beeta
        : gamma;

Vaihda - vaihdettaessa se on paras käytäntö

  • Käytä aina oletusasetusta myös ilman koodia
  • Käytä / * putoaa läpi * / osoittaaksesi, että säätö kuuluu seuraavaan tapaukseen
kytkin (kunto) {
  tapaus ABC:
    lausumat;
  / * putoaa läpi * /
  tapaus DEF:
    lausumat;
    tauko;
  oletus:
    lausumat;
     tauko;
}

Poikkeussanomat - Kun poiketaan poikkeuksesta, tässä on esimerkkejä hyvistä ja huonosti sisennetyistä viesteistä.

// Vältä (x) - Ei helppo lukea
heitä uusi IllegalStateException ("Pyynnön käsittely epäonnistui" + request.getId ()
    + "käyttäjälle" + käyttäjä.getId () + "kysely:" "+ kysely.getText ()
    + "'");
// Suosittelemme () - melko helpompi lukea
heitä uusi IllegalStateException ("Prosessi epäonnistui"
    + "pyyntö" + pyyntö.getId ()
    + "käyttäjälle" + user.getId ()
    + "kysely:" "+ kysely.getText () +" "");

Iteraattorit ja virrat - virrat ovat yleistymässä, ja toisinaan se voi olla erittäin monimutkainen, joten on tärkeätä sisäänsyöttää, jotta lukeminen olisi helppoa.

// Vältä (x) - Ei helppo lukea
Jäljittelemättömät  moduulit = ImmvableList.  builder (). Add (new LifecycleModule ())
    .add (uusi AppLauncherModule ()). addAll (application.getModules ()). build ();
// Suosittelemme () - melko helpompi lukea
Mitatut  moduulit = ImmvableList.  rakentaja ()
    .add (uusi LifecycleModule ())
    .add (uusi AppLauncherModule ())
    .addAll (application.getModules ())
    .rakentaa();
Seuraa vain koodausstandardia - mitä tahansa

Ilmoitukset ja toimeksiannot - Yksi riviä suositellaan, koska se kannustaa kommentteja alla esitetyllä tavalla.

// Suosittele ()
int tasolla; // sisennystaso
int sizeMeter; // pöydän koko
// Vältä (x) edellä mainittua
int tasolla, sizeMeter;
// Prefer () - Lisää yksikkö muuttujan nimeen tai tyyppiin
pitkä kyselyIntervalMs;
int tiedostoSizeGb;
Määrä  fileSize;
// Vältä (x) tyyppien sekoittamista
int foo, fooarray [];
// Vältä (x) - Älä erota pilkulla
Format.print (System.out, ”virhe”), exit (1);
// Vältä (x) useita tehtäviä
fooBar.fChar = barFoo.lchar = 'c';
// Vältä (x) upotettuja tehtäviä yrittää parantaa suorituskykyä // tai tallentaa rivi. Olen syyllinen tähän :(
d = (a = b + c) + r;
// Suosittele () yllä
a = b + c;
d = a + r;
// Suosittele ()
Merkkijono [] args
// Vältä (x)
Kielisarjat []
// Mieluummin () Käytä pitkään "L": n "l": n sijasta välttääksesi sekaannusta 1: llä
pitkä aikakatkaisu = 3000000000L;
// Vältä (x) - Vaikea sanoa, että viimeinen kirjain on l eikä 1
pitkä aikakatkaisu = 3000000000 l;

Laita ilmoitukset vain lohkojen alkuun (lohko on koodi, jota ympäröivät kihara-aukot {ja}). Älä odota muuttujien ilmoittamista ennen niiden ensimmäistä käyttöä. se voi sekoittaa varomattoman ohjelmoijan ja estää koodin siirrettävyyden rajoissa.

// Parempi () ilmoittaa lohkon alussa.
public void doSomething () {
  int mitä läsnä; // menetelmälohkon alku
  if (ehto) {
    int joitainFlag; // ”if” -lohkon alku
    ...
  }
}

On myös tärkeää välttää paikallisia ilmoituksia, joissa piilotetaan ylemmän tason ilmoitukset, ja välttää sekaannuksia, kuten alla on esitetty.

int määrä;
...
public void doSomething () {
  if (ehto) {
    int määrä; // VÄLTTÄÄ!
    ...
  }
  ...
}

Välit ja rivinvaihdot - Vältä kiusausta säästää 1–2 koodiriviä luettavuuden kustannuksella. Tässä on kaikki hyvät käytännöt välilyönteissä ja tyhjissä riveissä (välilyönnillä on eroa)

  • Yksi (1) tyhjä rivi menetelmien ja kevään kehittäjien välillä suosittelee kahta (2) tyhjää riviä konstruktorien, staattisen lohkon, kenttien ja sisäluokan jälkeen
  • Välilyöntioperaattorit, ts. Käytä int foo = a + b + 1; yli int foo = a + b + 1;
  • Erota kaikki binaarioperaattorit paitsi “.” Operandista välilyönnillä
  • Avoin ahdin “{” ilmestyy saman rivin loppuun kuin ilmoituslausunto tai menetelmä ja sulkeva ahdin “}” aloittaa rivin itsessään sisennettynä
// Prefer () - Tila välilyönnin jälkeen ja ennen "("
kun taas (totta) {
  ...
}
// Vältä (x) - Toisin kuin yllä ei ole tilaa
kun taas (totta) {
  ...
}
// Suosittele () - Ei tilaa "doSomething" ja "("
public void doSomething () {
  ...
}
// Vältä (x) - Toisin kuin edellä
public void doSomething () {
  ...
}
// Prefer () - Lisää välilyönti argumentin jälkeen
julkinen tyhjä doSomething (int a, int b) {
  ...
}
// Prefer () - Operandin ja operaattoreiden välinen tila (ts. +, =)
a + = c + d;
a = (a + b) / (c * d);
kun taas (d ++ = s ++) {
  n ++;
}

Asiakirjat ja kommentit

On syytä mainita, että melkein kaikki koodi muuttuu koko elinkaarensa ajan ja on joskus, kun sinä tai joku yrittää selvittää, mitä monimutkaisen koodilohkon, menetelmän tai luokan on tarkoitus tehdä, ellei selvästi kuvata. Todellisuus on melkein aina seuraava

Joskus monimutkaisen koodin, menetelmän, luokan kommentti ei tuo arvoa tai palvele sitä tarkoitusta. Tämä tapahtuu yleensä kommentoidessaan sen vuoksi.

Kommentteja tulisi käyttää antamaan yleiskatsaus koodista ja antamaan lisätietoja, joita ei ole helposti saatavilla koodissa. Aloitetaan. Kommentteja on kahta tyyppiä

Toteutuskommentit - on tarkoitettu kommentoimaan koodia tai kommentoimaan koodin tiettyä toteutusta.

Dokumentaatiokommentit - on tarkoitettu kuvaamaan koodin määritelmää toteutuksenvapaasta näkökulmasta ja lukea kehittäjille, joilla ei välttämättä ole lähdekoodia käsillä.

Kommenttien tiheys heijastaa joskus koodin heikkoa laatua. Kun sinusta tuntuu pakko lisätä kommentti, harkitse koodin kirjoittamista uudelleen selventämiseksi.

Tyypit toteutuskommentit

Toteutusta koskevia kommentteja on neljä (4), kuten alla on esitetty

  • Estä kommentti - katso alla oleva esimerkki
  • Yhden rivin kommentti - kun kommentti ei ole riviä pidempi
  • Viimeiset kommentit - Hyvin lyhyt kommentti siirrettiin oikeaan päähän
  • Rivin lopun kommentti - aloittaa kommentin, joka jatkuu uudelle riville. Se voi kommentoida kokonaisen rivin tai vain osittaisen rivin. Sitä ei tule käyttää peräkkäisillä useilla riveillä tekstikommentteihin; Sitä voidaan kuitenkin käyttää peräkkäisissä useissa riveissä kommentoimaan koodiosia.
// Estä kommentti
/ *
 * Käyttö: Tarjoaa kuvaus tiedostoista, menetelmistä, tietorakenteista
 * ja algoritmit. Voidaan käyttää kunkin tiedoston alussa ja
 * ennen kutakin menetelmää. Käytetään pitkissä kommenteissa, jotka eivät sovi a
 * yksi rivi. 1 Tyhjä rivi jatkaa estävän kommentin jälkeen.
 * /
// Yhden rivin kommentti
if (ehto) {
 / * Suorita kunto. * /
  ...
}
// Viimeinen kommentti
if (a == 2) {
 palata TOSTI; /* erikoistapaus */
} muuta {
 paluu isPrime (a); / * toimii vain parittomalla *
}
// Rivin lopun kommentti
if (foo> 1) {
  // Tee kaksinkertainen läppä.
  ...
} muuta {
  palauta väärä; // Selitä miksi täällä.
}
// if (palkki> 1) {
//
// // Tee kolminkertainen kääntö.
// ...
//}
// muu
// palauta väärä;

Asiakirjojen kommentit (ts. Javadoc)

Javadoc on työkalu, joka luo HTML-dokumentaatiota Java-koodistasi käyttämällä kommentteja, jotka alkavat / ** ja päättyvät * / - Katso Wikipediasta lisätietoja siitä, kuinka Javadoc toimii tai vain lukea.

Tässä on esimerkki Javadocista

/ **
 * Palauttaa kuvaobjektin, joka voidaan sitten maalata näytölle.
 * URL-argumentin on määritettävä ehdoton {@link URL}. Nimi
 * argumentti on määrittely, joka on suhteessa url-argumenttiin.
 * 

 * Tämä menetelmä palaa aina heti, riippumatta siitä, onko  * kuva on olemassa. Kun tämä appletti yrittää piirtää kuvan  * näyttö, tiedot ladataan. Grafiikan primitiivit  * kuvan piirtävät maalautuvat asteittain näytölle.  *  * @param url ehdoton URL, joka antaa kuvan perustan  * @param nimeä kuvan sijainti suhteessa url-argumenttiin  * @ käännä kuva määritettyyn URL-osoitteeseen  * @ katso kuva  * /  public Image getImage (URL-osoite, merkkijonon nimi) {         yrittää {             return getImage (uusi URL (URL, nimi));         } saalis (MalformedURLException e) {             palauta nolla;         }  }

Ja yllä oleva johtaisi seuraavaksi HTML-muotoon, kun javadocia ajetaan yllä olevaa koodia vastaan

Katso tästä lisää

Tässä on joitain avaintunnisteita, joiden avulla voit parantaa luodun Java-dokumentoinnin laatua.

@author => @author Raf
@code => {@koodi A  C}
@deprecated => @depreposed poistoviesti
@exception => @exception IOException heitetään kun
@link => {@link package.class # jäsenetiketti}
@param => @param parametrin nimen kuvaus
@return => Mitä menetelmä palaa
@ see => @ see "merkkijono" TAI @ katso  
@since => Ilmaisee version, kun julkisesti saatavilla oleva menetelmä lisätään

Katso täydellinen luettelo ja tarkempi kuvaus täältä

Twitterin koodausstandardi ei suosittele @author-tunnisteiden käyttöä

Koodi voi vaihtaa omistajaa useita kertoja elinaikanaan, ja lähdetiedoston alkuperäisellä kirjoittajalla ei useinkaan ole merkitystä useiden iteraatioiden jälkeen. Katsomme, että on parempi luottaa sitoutumishistoriaan ja OWNERS-tiedostoihin, jotta voidaan määrittää koodin kokonaisuus.

Seuraavassa on esimerkkejä siitä, kuinka voit kirjoittaa oivallisen dokumentaatio-kommentin, kuten Twitterin koodausstandardissa kuvataan

// huono.
// - Asiakirja ei kerro mitään, mitä menetelmäilmoituksella ei ollut.
// - Tämä on 'täyttöasiakirja'. Se läpäisi tyyliketit, mutta
ei auta ketään.
/ **
 * Halkaise merkkijonon.
 *
 * @param s Merkkijono.
 * @return Lista merkkijonoista.
 * /
Lista  split (merkkijonot);
// Parempi.
// - Tiedämme, mihin menetelmä jakaa.
// - Vielä jotain määrittelemätöntä käyttäytymistä.
/ **
 * Jakaa merkkijonon välilyöntiin.
 *
 * @param s Jaettava merkkijono. {@Code null} -merkkijonoa käsitellään tyhjänä merkkijonona.
 * @return Luettelo sisääntulon välilyönnillä rajatuista osista.
 * /
Lista  split (merkkijonot);
// Loistava.
// - Kattaa vielä yhden reunakotelon.
/ **
 * Jakaa merkkijonon välilyöntiin. Toistetut välilyönnit
 * ovat romahtaneet.
 *
 * @param s Jaettava merkkijono. {@Code null} -merkkijonoa käsitellään tyhjänä merkkijonona.
 * @return Luettelo sisääntulon välilyönnillä rajatuista osista.
 * /
Lista  split (merkkijonot);

Kommenttien kirjoittamisessa on tärkeää olla ammattitaitoista

// Vältä (x)
// Vihaan xml / saippuaa niin paljon, miksi se ei voi tehdä tätä minulle !?
yrittää {
  userId = Integer.parseInt (xml.getField ("id"));
} kiinni (NumberFormatException e) {
  ...
}
// Suosittele ()
// TODO (Jim): Poista kenttävalidointi kirjastosta.
yrittää {
  userId = Integer.parseInt (xml.getField ("id"));
} kiinni (NumberFormatException e) {
  ...
}

Ja on tärkeätä pitää mielessä, että et dokumentoi ohitettua menetelmää, ellei toteutus ole muuttunut.

Ja tässä on vielä muutama mielessä pidettävä kohta

  • Vältä jokerimerkkien tuontia - kuten Twitterin koodausstandardeissa kuvataan, se tekee luokan lähteestä vähemmän selkeän. Työskentelen ryhmässä, jossa on useita Eclipse- ja IntelliJ-käyttäjiä, ja sain selville, että Eclipse poistaa yleismerkkien tuonnin ja IntelliJ esittelee sen. On todennäköisesti mahdollista kytkeä se pois päältä. Halusin vain huomauttaa kahden oletus.
  • Käytä aina @Override-merkintää ohittaessasi
  • Kannusta @Nullable: n käyttöä, kun kenttä tai menetelmä palaa nollaksi
  • Käytä tulevia töitä varten erityisiä kommentteja ja muista jättää viittaus itseesi, jotta muut tietävät kenen kysyä Y-kysymystä sen sijaan, että arvasisit, poistaisit tai tarkistaaksesi syyllisyyttä löytääksesi sen, joka lisäsi sen. Jotkut IDE: t, kuten Eclipse ja IntelliJ, auttavat myös näiden luetteloinnissa, jotta niitä olisi helppo käyttää ja muistutusta.
// FIXME (Raf): Toimintakelpoinen viesti kuvaa, mitä on tehtävä
// TODO (Raf): Toimintakelpoinen viesti kuvaa, mitä on tehtävä

Loppupeli on kirjoittaa koodi, joka helpottaa tulevien kirjoittajien ja ylläpitäjien elämää.

Loppupeli

Muut asiaankuuluvat lukumateriaalit

Luettelo asiaankuuluvista artikkeleista, jotka ovat merkityksellisiä puhtaan, rakenteellisen, helposti luettavan ja ylläpidettävän koodin kirjoittamisessa. Jos haluat lukea lisää, suosittele ehdottomasti seuraavaa

ja toinen hyvä luettelo vinkkejä puhtaan koodin kirjoittamiseen