Кратак резиме најбољих пракси кодирања Јава

заснована на стандардима кодирања од стране Орацле, Гоогле-а, Твиттера и Спринг Фрамеворк-а

Циљ овог чланка је да вам пружите кратак резиме послова и немојте другим речима да преферирате и избегавате на основу стандарда кодирања технолошких дивова као што су Орацле, Гоогле, Твиттер и Спринг Фрамеворк.

Можда се или не слажете са неким од најбољих овде представљених пракси, и то је сасвим у реду док постоји неки стандард за кодирање.

Зашто стандарди кодирања на првом мјесту? Много је добрих разлога ако то поставите на Гоогле, а ја ћу вам оставити следећу илустрацију

Документ са стандардима кодирања може бити дуготрајан и досадан. Овај чланак трешња бира комаде и комаде из конвенција кодирања од стране Гоогле-а, Орацле-а, Твиттера и Спринг-а, а циљ му је да вам омогући једноставан праћење и мање досадан низ пракси како би код био лак за читање и одржавање.

Скоро увек ћете се придружити тимовима који раде на постојећем софтверу и постоји прилично добра шанса да је већина аутора напустила или прешла на различите пројекте, остављајући вас на сметају са деловима кода који вас доводе у питање хуманост.

Уђимо у најбоље праксе из различитих стандарда кодирања.

Јава изворна датотека

Следеће се сматра најбољом праксом када су у питању изворне датотеке Јава:

  • Дужина изворне датотеке је мања од 2.000 линија кода
  • Изворна датотека је организована с коментаром документације, декларацијом пакета, затим коментаром класе, увозом групираним (статички задњи), потписом класе / интерфејса и тако даље, као што је приказано у наставку
пацкаге цом.екампле.модел;
/ **
 * Перспектива без примјене коју треба да прочитају програмери
 * који можда не морају да имају изворни код при руци
 *
 * @аутхор к, и, з
 * @дате
 * @верзија
 * @Ауторско право
 *
 * /
импорт цом.екампле.утил.ФилеУтил;
/ *
 * Необавезан коментар специфичан за класу
 *
 * /
јавна класа СомеЦласс {
  // Статичке променљиве према редоследу видљивости
  јавни статички коначни цели број ПУБЛИЦ_ЦОУНТ = 1;
  статички крајњи цели број ПРОТЕЦТЕД_ЦОУНТ = 1;
  приватни статички коначни цели број ПРИВАТЕ_ЦОУНТ = 1;
  // Променљиве инстанце према редоследу видљивости
  назив јавног низа;
  Стринг посталЦоде;
  приватна стринг адреса;
  // Конструктор и преоптерећен редоследом
  јавни СомеЦласс () {}
  јавни СомеЦласс (Стринг наме) {
    тхис.наме = име;
  }
  // Методе
  јавни Стринг доСометхингУсефул () {
    повратак "Нешто корисно";
  }
  // геттерс, сеттерс, екуалс, хасхЦоде и тоСтринг на крају
}

Именовање

Називи класа и интерфејса су ЦамелЦасе и препоручује се употреба целе речи и избегавање акронима / скраћеница. На пример, класа Растер или класа ИмагеСприте

  • Пакет - именује цом.деепспаце преко цом.деепСпаце или цом.дееп_спаце
  • Имена датотека су ЦамелЦасе и завршавају се с .јава подударањем с именом класе. Постоји једна јавна класа по датотеци са сваком врстом највишег нивоа у својој датотеци
  • Метода - имена би требало да буду глаголи у мешовитом случају са сваком унутрашњом речју с великим словом, на пример рун (); или рунФаст ();
  • Константе - треба бити велика слова са „_“ одвајањем сваке речи, на пример инт МИН_ВИДТХ = 44; и инт МАКС_ВИДТХ = 99;
  • Вариабле - назив који читаоцу програма говори шта варијабла представља, тј. Ако чувате тестну оцену, а затим изаберите оцену вс вар1. Имена променљивих би требало да буду кратка, а не укључују метаподатке.
// Префер (✔) - кратка имена променљивих и описују шта се чува
инт сцхоолИд;
инт [] филтриранеСцхоолИдс;
инт [] јединствениСцхоолдИдс;
Мапа <Интегер, Усер> усерсБиИд;
Стринг валуе;
// Избегавајте (к) - Превише детаљно именовање променљивих
инт сцхоолИдентифицатионНумбер;
инт [] усерПровидедСцхоолИдс;
инт [] сцхоолИдсАфтерРемовингДуплицатес;
Мапа <Интегер, Усер> идТоУсерМап;
Стринг валуеСтринг;

Запамтите - назив променљиве треба да буде кратак и да читаоцу лако каже коју вредност представља. Искористите свој суд.

Преферирајте и избегавајте

Форматирање и одступања односе се на организовање кода ради лакшег читања, а укључује размаке, дужину линије, облоге и провале и тако даље

  • Удубљење - користите 2 или 4 размака и будите доследни
  • Дужина линије - До 70 до 120 знакова, зависно од утицаја на читљивост. Важно је да се елиминише потреба за хоризонталним померањем и постављањем прекида линија након зареза и оператера.

Методе - Ево листе најбољих пракси

// Префер (✔) Преломи линија су произвољни и прелазе након зареза.
Преузимање жицаАнИнтернет (Интернет интернет, цеви за цеви,
    Блогови блогова, Количина <Лонг, Подаци> опсег) {
  тубес.довнлоад (интернет);
}
// Избегавајте (к) Тешко разликујуће аргументе метода тела методе
Преузимање жицаАнИнтернет (Интернет интернет, цеви за цеви,
    Блогови блогова, Количина <Лонг, Подаци> опсег) {
    тубес.довнлоад (интернет);
}
// Префер (✔) Додајте 8 (дупло од 2 или 4) размака за дубоку увлаку
приватни статички синхронизовани хоркингЛонгМетходНаме (инт анАрг,
        Објецт анотхерАрг, Стринг иетАбодиАрг,
        Објецт андСтиллАгетхер) {
  ...
}
// Преферирајте (✔) Једноставно скенирање и додатни простор у колони.
јавни Стринг довнлоадАнИнтернет (
    Интернет Интернет,
    Цеви цеви,
    Блогови блогосфере,
    Износ <Дуг, Подаци> опсег) {
  тубес.довнлоад (интернет);
  ...
}
Јединствени тест би то ухватио

Ако се провере - ИМО писање добро форматираног кода олакшава уочавање погрешака при упису и грешака аутору и рецензентима кода, погледајте доле:

// Избегавајте (к) Не изостављајте {}
ако (услов)
  изјава;
// Избегавајте (к)
ако је (к <0) негативан (к);
// Избегавајте (к)
иф (а == б&& ц == д) {
...
}
// Префер (✔)
ако је ((а == б) && (ц == ​​д)) {
...
}
// Префер (✔)
иф (услов) {
  изјаве;
} елсе иф (услов) {
  изјаве;
} елсе иф (услов) {
  изјаве;
}
// Избегавајте (к)
иф ((услов1 и услов2)
    || (цондитион3 && цондитион4)
    ||! (цондитион5 && цондитион6)) {// БАД ВРАПС
    доСометхинг АбоутИт (); // ОВУ ЛИНИЈУ ЛАКО МИСЛИТЕ
}
// Префер (✔)
иф ((услов1 и услов2)
        || (цондитион3 && цондитион4)
        ||! (услов5 и услов6)) {
    доСометхинг АбоутИт ();
}

Тернарни оператер - И испод су препоручене праксе

алфа = (аЛонгБоолеанЕкпрессион)? бета: гама;
алфа = (аЛонгБоолеанЕкпрессион)? бета
        : гама;
алфа = (аЛонгБоолеанЕкпрессион)
        ? бета
        : гама;

Пребацивање - Када је у питању прелазак, најбоља је пракса

  • Увек имате подразумевани случај, чак и без кода
  • Користите / * пада кроз * / да назначите да контрола пада на следећи случај
прекидач (услов) {
  случај АБЦ:
    изјаве;
  / * пада кроз * /
  случај ДЕФ:
    изјаве;
    пауза;
  Уобичајено:
    изјаве;
     пауза;
}

Поруке изузетака - Када бацате изузетак, овде су узорци добрих и слабо разведених порука.

// Избегавајте (к) - Није лако читати
бацити нову ИллегалСтатеЕкцептион ("Неуспјешно обрађивање захтјева" + рекуест.гетИд ()
    + "за корисника" + усер.гетИд () + "куери: '" + куери.гетТект ()
    + "'");
// Префер (✔) - Прилично лакше за читање
избаци нову ИллегалСтатеЕкцептион ("Неуспешно обрађивање"
    + "захтев" + рекуест.гетИд ()
    + "за корисника" + усер.гетИд ()
    + "куери: '" + куери.гетТект () + "'");

Итератори и токови - Токови постају све чешћи и понекад могу бити врло сложени, па је важно увлачити увлаке ради лаког читања.

// Избегавајте (к) - Није лако читати
Итерабле <Модуле> модуле = ИммутаблеЛист. <Модуле> буилдер (). Адд (нови ЛифецицлеМодуле ())
    .адд (нови АппЛаунцхерМодуле ()). аддАлл (апплицатион.гетМодулес ()). буилд ();
// Префер (✔) - Прилично лакше за читање
Итерабле <Модуле> модуле = ИммутаблеЛист. <Модуле> буилдер ()
    .адд (нови ЛифецицлеМодуле ())
    .адд (нови АппЛаунцхерМодуле ())
    .аддАлл (апплицатион.гетМодулес ())
    .буилд ();
Само следите стандард кодирања - заиста било који

Изјаве и задатци - Препоручује се једна декларација по линији јер подстиче коментаре као што је приказано у наставку.

// Префер (✔)
инт ниво; // ниво удубљења
инт сизеМетер; // величина стола
// Избегавајте (к) у прилог горе наведеном
инт ниво, сизеМетер;
// Префер (✔) - Укључи јединицу у назив или врсту променљиве
дуга анкетаИнтервалМ;
инт филеСизеГб;
Износ <Интегер, Дата> филеСизе;
// Избегавајте (к) типове мешања
инт фоо, фооарраи [];
// Избегавајте (к) - Не одвајајте се зарезом
Формат.принт (Систем.оут, „грешка“), излаз (1);
// Избегавајте (к) вишеструко додељивање
фооБар.фЦхар = барФоо.лцхар = 'ц';
// Избегавајте (к) уграђене задатке у покушају да повећате перформансе // или сачувате линију. Ја сам крив за ово :(
д = (а = б + ц) + р;
// Преферирајте (✔) изнад
а = б + ц;
д = а + р;
// Префер (✔)
Стринг [] аргс
// Избегавајте (к)
Стринг аргс []
// Дајте предност (✔) Дуго користите „Л“ уместо „л“ да бисте избегли пометњу са 1
дуго време = 3000000000Л;
// Избегавајте (к) - тешко је рећи да је последње слово л, а не 1
дуго време = 3000000000л;

Декларацију ставите само на почетак блокова (Блок је код окружен коврчавим заградама {и}). Не чекајте да декларишете променљиве до њихове прве употребе; може збунити непажљивог програмера и ометати преносивост кода у оквиру.

// Префер (✔) изјавити на почетку блока.
публиц воид доСометхинг () {
  инт вхатИРепресент; // почетак блока метода
  иф (услов) {
    инт сомеФлаг; // почетак блока „ако“
    …
  }
}

Такође је важно избегавати локалне декларације које сакривају декларације виших нивоа и избегавати забуне као што је приказано у наставку

инт цоунт;
...
публиц воид доСометхинг () {
  иф (услов) {
    инт цоунт; // ИЗБЕГАВАЈТЕ!
    ...
  }
  ...
}

Размаци и пробоји линија - Избегавајте искушење да сачувате 1-2 ретка кода на штету читљивости. Овде су све најбоље праксе када је реч о размаку и празним линијама (бели простор заиста прави разлику)

  • Једна (1) празна линија између метода и Спринг програмери препоручују две (2) празне линије након конструктора, статички блок, поља и унутрашње класе
  • Оператори свемирске плоче, тј. Користите инт фоо = а + б + 1; преко инт фоо = а + б + 1;
  • Одвојите све бинарне операторе осим „.“ Од операнда који користе размак
  • Отворена заграда „{“ појављује се на крају исте линије као декларација или метода декларације, а затварајућа заграда „}“ покреће линију сама са разрезом
// Префер (✔) - размак након "док" и пре "("
док је (тачно) {
  ...
}
// Избегавајте (к) - за разлику од горњег простора
док је (тачно) {
  ...
}
// Префер (✔) - Нема размака између "доСометхинг" и "("
публиц воид доСометхинг () {
  ...
}
// Избегавајте (к) - за разлику од горњег простора
публиц воид доСометхинг () {
  ...
}
// Префер (✔) - Додајте размак након аргумента
публиц воид доСометхинг (инт а, инт б) {
  ...
}
// Префер (✔) - размак између операнда и оператора (тј. +, =)
а + = ц + д;
а = (а + б) / (ц * д);
док је (д ++ = с ++) {
  н ++;
}

Документација и коментари

Вреди напоменути да се скоро цео код мења током свог животног века и постојаће тренуци када ви или неко покушавате да схватите шта треба да ради сложен блок кода, метода или класе ако није јасно описано. Реалност је скоро увек таква као што следи

Понекад коментари на сложени део кода, методе, класе не додају никакву вредност нити служе његовој сврси. То се обично дешава када коментаришете ради њега.

Коментари се требају користити за преглед прегледа кода и пружање додатних информација које нису доступне у самом коду. Хајде да почнемо. Постоје две врсте коментара

Коментари имплементације - имају за циљ да коментирају код или коментар о одређеној имплементацији кода.

Коментари документације - желе описати спецификацију кода из перспективе без имплементације коју треба да читају програмери који можда не морају имати при руци изворни код.

Учесталост коментара понекад одражава лош квалитет кода. Када будете приморани да додате коментар, размислите о преписивању кода да би био јаснији.

Врсте коментара о имплементацији

Постоје четири (4) врсте коментара за имплементацију као што је приказано у наставку

  • Блокирај коментар - погледајте доњи пример
  • Коментар са једном линијом - када коментар није дужи од ретка
  • Последњи коментари - Врло кратак коментар премештен је на прави крај
  • Коментар на крају линије - започиње коментар који наставља у нови ред. Може коментарисати потпуну или само делимичну линију. Не треба га користити у више узастопних линија за коментаре текста; међутим, може се користити у више узастопних редака за коментарисање делова кода.
// Блокирај коментар
/ *
 * Употреба: Пружа опис датотека, метода, структура података
 * и алгоритми. Може се користити на почетку сваке датотеке и
 * пре сваке методе. Користи се за дуге коментаре који не одговарају
 * једна линија. 1 Празна линија за наставак након коментара на блоку.
 * /
// Коментар у једној линији
иф (услов) {
 / * Ријешите стање. * /
  ...
}
// Траилинг цоммент
ако је (а == 2) {
 вратити ТРУЕ; /* специјалан случај */
} елсе {
 повратак је ПРИМЕР (а); / * ради само за непарни * /
}
// Коментар на крају линије
ако (фоо> 1) {
  // Урадите двоструки окрет.
  ...
} елсе {
  ретурн фалсе; // Објасните зашто овде.
}
// иф (бар> 1) {
//
// // Урадите троструки окрет.
// ...
//}
// елсе
// ретурн фалсе;

Коментари документације (тј. Јавадоц)

Јавадоц је алат који генерира ХТМЛ документацију из вашег Јава кода користећи коментаре који почињу са / ** и завршавају са * / - за више детаља погледајте како функционира Јавадоц или само читајте.

Ево примера Јавадоца

/ **
 * Враћа објект слике који се затим може сликати на екрану.
 * Аргумент УРЛ мора да наведе апсолутни {@линк УРЛ}. Име
 * аргумент је спецификатор који је у односу на аргумент урл.
 * <п>
 * Ова метода се увек враћа одмах, без обзира да ли је
 * слика постоји. Када овај аплет покушава да привуче слику
 * на екрану, подаци ће бити учитани. Графички примитиви
 * који цртају слику постепено ће се сликати на екрану.
 *
 * @парам урл апсолутни УРЛ даје основну локацију слике
 * @парам име локације слике у односу на аргумент УРЛ-а
 * @ вратите слику на наведени УРЛ
 * @ види слику
 * /
 јавна слика гетИмаге (УРЛ адреса, назив низа) {
        покушати {
            вратити гетИмаге (нови УРЛ (УРЛ, име));
        } хватање (МалформедУРЛЕкцептион е) {
            ретурн нулл;
        }
 }

А горе наведено резултира ХТМЛ-ом као што слиједи када се јавадоц покрене против кода који има горе наведено

Погледајте овде за више

Ево неколико кључних тагова које можете користити да побољшате квалитет генерисане јава документације.

@аутхор => @аутхор Раф
@цоде => {@цоде А <Б> Ц}
@депрецатед => @депрепосед депрецатион-мессаге
@екцептион => @екцептион ИОЕкцептион бачен када
@линк => {@линк пацкаге.цласс # чланска налепница}
@парам => @парам опис параметра
@ретурн => Шта метода враћа
@сее => @сее "стринг" ИЛИ @ види <а ...> 
@синце => За навођење верзије када се дода јавно доступан метод

Комплетан списак и детаљнији опис погледајте овде

Твиттер-ов стандард за кодирање саветује употребу ознаке @аутхор

Код може мењати руке више пута током свог животног века, а често је оригинални аутор изворне датотеке неважан након неколико итерација. Сматрамо да је боље да верујемо историји предавања датотека и власницима датотека да бисте утврдили власништво над целином кода.

Следе примери како можете написати коментар документације који је увидан као што је описано у Твиттер-овом стандарду за кодирање

// Бад.
// - Документ не говори ништа што декларација методе није.
// - Ово је „доц филлер“. Прошло би проверу стила, али
не помаже никоме.
/ **
 * Подељује низ.
 *
 * @парам с А стринг.
 * @ретурн Листа низова.
 * /
Листа <Стринг> сплит (Стринг с);
// Боље.
// - Знамо на шта се та метода дели.
// - Ипак неко недефинисано понашање.
/ **
 * Подељује низ на размаку.
 *
 * @парам с Низ за поделу. {@Цоде нулл} низ се третира као празан низ.
 * @ретурн Листа делова улаза који је разграничен размаком.
 * /
Листа <Стринг> сплит (Стринг с);
// Сјајно.
// - Покрива још један рубни случај.
/ **
 * Подељује низ на размаку. Понављани знакови белог простора
 * су урушени.
 *
 * @парам с Низ за поделу. {@Цоде нулл} низ се третира као празан низ.
 * @ретурн Листа делова улаза који је разграничен размаком.
 * /
Листа <Стринг> сплит (Стринг с);

Када је у питању писање коментара, важно је бити професионалан

// Избегавајте (к)
// толико мрзим кмл / сапун, зашто то не може учинити за мене !?
покушати {
  усерИд = Интегер.парсеИнт (кмл.гетФиелд ("ид"));
} хватање (НумберФорматЕкцептион е) {
  ...
}
// Префер (✔)
// ТОДО (Јим): Потврђивање потврде поља у библиотеци.
покушати {
  усерИд = Интегер.парсеИнт (кмл.гетФиелд ("ид"));
} хватање (НумберФорматЕкцептион е) {
  ...
}

И важно је имати на уму да се документовани метод не документује уколико се имплементација није променила.

И ево још неколико тачака које морате имати на уму

  • Избегавајте увоз скривених знакова - као што је описано у Твиттер стандардима шифрирања, извор класе чини мање јасним. Радим у тиму са мешавином корисника Ецлипсе и ИнтеллиЈ и сазнао сам да Ецлипсе уклања увоз великих узорака и ИнтеллиЈ га уводи. Вероватно постоји опција да се искључи, само сам хтео да укажем на подразумевана два.
  • Увек користите @Оверриде напомену приликом прегласавања
  • Подстакните употребу @Нуллабле када поље или метода врате нулу
  • Искористите посебне коментаре за будући рад и не заборавите да оставите референцу на себе како би други знали коме да поставе своје И питање уместо да нагађају, уклањају га или проверавају кривицу гита да би пронашли ко га је додао. Неки ИДЕ-ови као што су Ецлипсе и ИнтеллиЈ такође помажу у пописивању њих ради лакшег приступа као и подсетник.
// ФИКСМЕ (Раф): Доступна порука описује шта треба учинити
// ТОДО (Раф): Доступна порука описује шта треба учинити

Крајња игра је писање кода који ће олакшати живот будућим ауторима и одржаваоцима.

Крајња игра

Остали релевантни материјали за читање

Листа релевантних чланака који су релевантни за писање кода који је чист, добро структуиран, једноставан за читање и одржавање. Ако желите да прочитате више, свакако препоручите следеће

и још једна добра листа савета за писање чистог кода