Практики за кодиране, които биха улеснили живота на вас и вашите колеги разработчици

Най-добрите практики за кодиране в Java често се пренебрегват от разработчиците поради липса на знания или време за прилагането им. Въпреки това, времето, което отделяте за изучаване и прилагане на най-добри практики, е по-голяма инвестиция, отколкото можете да осъзнаете.

Най-добрите практики, обсъдени в тази статия, са предназначени както за младши, така и за старши Java разработчици. Тези най-добри практики ще ви помогнат да подобрите производителността, да намалите рисковете за сигурността, да запазите паметта на купчината и да опростите отстраняването на грешки, така че да спестите много време. Да започваме.

Използвайте правилни конвенции за именуване

Ако знаете какво прави нещо, имате доста добър шанс да познаете името на класа Spring или интерфейса за него.

Род Джонсън, създателят на рамката Spring, направи горното изявление, за да подчертае важността на спазването на конвенциите за именуване. Такива конвенции за именуване трябва да се следват и във вашия Java код.

Добре оформеното име не само помага при четенето на кода, но също така предава много за намерението на кода. Нека да разгледаме пример от реалния свят.

public class User{     
    private String userName;     
    public void setUserName(String userName){  
        this.userName = userName;     
    } 
}

Както можете да видите от предходния пример,

  • Имената на класове или интерфейси трябва да са съществителни, защото те представляват обекти от реалния свят.
  • Имената на методите трябва да са глаголи, защото те винаги са част от класа и представляват действие като цяло.
  • Имената на променливите трябва да са кратки, но смислени, а имената на променливи с един знак трябва да се избягват, освен за временни променливи, като итератори на цикъл.

Така че, вместо да запълвате кода си с безсмислени имена, използвайте смислени имена, които ще улеснят вашите колеги разработчици, инженери по осигуряване на качеството или дори вас самите да разбират кода в бъдеще.

Минимизиране с помощта на оператора „+“ за конкатенация на низове

Използването на оператора „+“ в Java за свързване на низове е често срещана практика сред много разработчици, включително и мен. Въпреки това, когато свързвате множество низове, операторът „+“ е неефективен, тъй като компилаторът на Java създава множество междинни обекти String, преди да създаде окончателния конкатениран низ.

Това разпределение на паметта за всеки низ забавя програмата и в крайна сметка може да погълне цялата ви хийп памет.

Решението и най-добрата практика в Java би било да се използват класовете StringBuilder или StringBuffer. Вградените функции в тези класове, като append(), могат да свържат два низа, без да създават междинни низови обекти, спестявайки време за обработка и използване на паметта.

StringBuilder sbd = new StringBuilder("0");
for (int i = 1; i < 100; i++) {
    sbd.append(", "+i);        
}

Можете да научите как да използвате StringBuilder и StringBuffer от моята статия по-долу.



Избягвайте променливостта на обекта

Състоянието на обекта и променливите стойности на променливи обекти могат да се променят по време на техния жизнен цикъл. Тъй като много променливи могат да сочат към един и същи екземпляр, проследяването кога и къде се е променило състоянието на обекта може да стане трудно. Това е убедителна причина да избягвате променящите се обекти, когато е възможно.

Неизменните обекти, от друга страна, не променят вътрешното си състояние с течение на времето, безопасни са за нишки и нямат странични ефекти. Поради тези характеристики, неизменните обекти са особено полезни в многонишкови среди.

Най-основният начин за постигане на неизменност е да направите всички променливи полета private и final, така че да не могат да бъдат итерирани, след като бъдат инициализирани. Рамката Spring ви позволява да запазите обектите неизменни, като използвате модела за инжектиране на зависимости constructor.

Сеч

Значението на регистрирането в разработката и особено в поддръжката не може да бъде надценено. Всеки разработчик на Java, който някога е правил отстраняване на грешки в производствен код, е пожелал повече регистрационни файлове в даден момент.

API за регистриране на Java, който се намира в java.util.logging package, ви позволява да проследявате грешки във вашите приложения. Когато повикване за регистриране се генерира от приложение, Logger записва събитието в LogRecord. След това той изпраща до съответните манипулатори или добавки.

В Java има множество библиотеки и рамки за регистриране, включително SLF4J и Logback. Докато те правят регистрирането в кодова база относително лесно, трябва да се уверите, че се придържате към най-добрите практики за регистриране. В противен случай небрежното регистриране може да се превърне в кошмар за поддръжка, а не в благодат. Нека да разгледаме някои от тези най-добри практики:

  • Избягвайте прекомерното регистриране и вземайте предвид само информацията, която може да бъде полезна при отстраняване на неизправности.
  • Изберете внимателно нивата на регистрационния файл; може да се наложи да активирате нивата на журнал селективно при производството.
  • За по-бързи анализи използвайте външни инструменти за проследяване, агрегиране и филтриране на регистрационни съобщения.

Нека да разгледаме пример за правилно описателно регистриране.

logger.info(String.format(“A new user has been created with userId: %s”, userId));

Винаги проверявайте за предпоставки за параметри

Винаги трябва да проверявате входните параметри на вашите публични методи, преди да изпълните каквато и да е логика, за да осигурите толерантност към грешки. Твърденията на Java са най-добрият начин за валидиране на параметрите на метода. В следващия пример, ако възрастта е по-малка от нула, се хвърля AssertionError.

public void setAge(int age) {
    assert age >= 0 : "Age should be positive";
}

Забележка: За да избегнете влияние върху производителността на производствената система, можете да деактивирате твърденията по време на изпълнение.

Друг вариант е да използвате Google Guava, където класът Preconditions може да се използва за валидиране на параметрите. Guava предоставя по-голяма гъвкавост от основното твърдение на Java.



Избягвайте празни блокове за улов

Писането на правилно и смислено съобщение в блока catch при обработка на изключения е най-добрата практика на Java, предпочитана от елитни разработчици. Начинаещите разработчици често оставят catch блоковете празни в началото, защото те са единствените, които работят върху кода. Въпреки това, когато изключение бъде уловено от празен catch блок, програмата не показва нищо, което превръща отстраняването на грешки в кошмар.

Освен това, необработени или отпечатани следи на стека на изключения могат да направят вашето приложение уязвимо за атаки чрез инжектиране.

Следователно е изключително важно да се обработват правилно изключенията в catch блок. Примерът по-долу демонстрира как правилно да използвате catch блок.

try {                
    doSomeWork();        
} catch (NullPointerException e) {  
    log("Exception occurred", e);
    response.sendError(
        HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
        "Exception occurred");
    return;
}

В примера регистрираме проследяването на стека и връщаме неразкриващ отговор, за да попречим на нападателите да видят проследяването на стека.

Избягвайте излишната инициализация

Не е необходимо и излишно изрично да се задават стойности на 0, false или null за полета или компоненти на масив.

По подразбиране Java задава стойностите на полетата или компонентите на масива на стойностите, изброени по-горе. Тази функция беше специално включена в Java, за да се намали повтарящото се кодиране, така че трябва да се възползваме от нея.

Плаване или двойно?

Неопитни разработчици често използват float и double в неподходящ контекст. Обикновено отиват само за един тип, независимо от изискванията. Използването на float или double трябва да се определя от изискванията.

Ако имате нужда от точни изчисления, трябва да се използва double вместо float. Тъй като повечето процесори отнемат почти еднакво време за обработка на float или double операции, но double предлага много по-голяма точност от float.

Когато прецизността не е проблем, можете да използвате float вместо double, защото заема половината от пространството в паметта, отколкото double.

Не забравяйте, че използването на подходящ тип данни ще подобри производителността на вашия код.

Най-добрият начин за проверка на странността

Виждал съм много разработчици да използват i % 2 == 1 веднага, за да видят дали дадено число е нечетно или не, което е неправилно. Това се дължи на факта, че е валиден само за положителни числа. Така че следният метод е правилният начин за проверка на странността на положително и отрицателно число в Java.

public boolean isOdd(int num) {
   return (num % 2 != 0)
}

Въпреки че това е правилно, това не е най-добрата практика на Java. Тъй като побитовият оператор И е много по-бърз от аритметичния модулен оператор, използването на метода по-долу за проверка за странност е най-добрата практика в Java.

public boolean isOdd(int num) {
   return (num & 1) != 0;
}

Избягване на изтичане на памет

Въпреки че Java управлява автоматично паметта и избягва повечето изтичания на памет, изтичане на памет може и ще възникне, ако не се следват правилните практики. Някои най-добри практики за избягване на изтичане на памет по време на кодиране включват винаги освобождаване на връзки към база данни след приключване на заявката, използване на блока finally възможно най-често, избягване на вътрешни класове и освобождаване на екземпляри, съхранени в статични таблици.

Налични са и множество инструменти, които да ви помогнат да откриете изтичане на памет във вашия код.

  • Разделът Памет в IntelliJ IDEA ви позволява да видите подробности за всички обекти в купчината, което ще ви помогне при откриването на изтичане на памет и техните причини. В IntelliJ можете също да използвате прозореца на инструмента Profiler, за да заснемете „моментни снимки на паметта“ на работещи процеси и да ги анализирате за течове.
  • Анализаторът на паметта (MAT) в Eclipse ви позволява да изследвате купчината на Java за изтичане на памет и да намалите потреблението на памет. Можете лесно да анализирате хейп дъмпове, дори ако съдържат милиони обекти, и да преглеждате размерите на всеки обект.
  • NetBeans Profilerможе да се използва за анализиране на използването на паметта в Java SE, Java FX, EJB, мобилни приложения и уеб приложения.
  • Освен това, можете да използвате инструмента Java Flight Recorder или инструмента с отворен код VisualVM за отстраняване на грешки при изтичане на памет във вашето приложение.

Изтичането на памет във вашето приложение може значително да влоши производителността, така че не забравяйте да ги избегнете, като следвате най-добрите практики, изброени по-горе.

Това е всичко за тази статия. Надявам се, че ще следвате тези най-добри практики, за да сте сигурни, че кодът ви е чист и приложението ви е ефективно.

Благодаря ви за четенето и приятно кодиране!