Сообщение администратору
Имя:
Почта:
Сообщение:
Вход на сайт
Логин:
Пароль:

Поддержка  •  Дневник  •  О сайте  •  Реклама  •  Поставить баннер  •  Прислать  •  Хроника  •  Translate  •  Рекомендованное  •  Написать администратору Гости: 24    Участники: 0 Авторизация Авторизация   Регистрация 
Метод Научного Тыка
RULVEN
Поиск  
Blackball iMag | интернет-журнал
RSS-лента
Поделиться ссылкой:
Каталог


Начало » Разработка ПО » 10 принципов хорошего программного кода, который устроит всех

10 принципов хорошего программного кода, который устроит всех


10 принципов хорошего программного кода, который устроит всех
Добавлено: Пн 14.01.2019 • Sergeant
Источник: источник
Просмотров: 273
Комментарии: 0


Чтобы от программного кода не отмахивались собеседующие или коллеги, он должен быть удобоваримым. Как написать «конфетку», которая понравится всем?

Роберт Мартин когда-то сказал, что единственным допустимым измерением качества кода является «Что за…».

Позвольте объяснить. Всякий раз, когда на глаза попадается какой-либо код, возникает одна из трех эмоций:

«Что за…», произнесенное с отвращением – этот код вообще не нужен.
«Что за…», выражающее восхищение – «Эй, а ведь этот парень действительно крут!»
«Что за…» с раздражением – в представленном коде невозможно разобраться.

Так что отвечает за реакцию на код? Это чистота кода. Писать чистый и предельно понятный код – признак настоящего профессионала. Как этого добиться?

Такое мастерство создано из двух главных составляющих: знания и работы. Знание учит вас шаблонам, принципам, практике и эвристике, которые необходимы для постоянного совершенствования. Но это знание должно быть подтверждено практикой, без которой оно попросту не будет закрепляться.

Так что красота программного кода – это не так уж просто, и если собеседующему что-то не понравилось, не расстраивайтесь: помните, что это все придет с опытом. В этой статье мы собрали десять принципов по-настоящему хорошего кода.

«Могу ли я узнать ваше имя?»

В программировании имена повсюду. Мы называем функции, классы, аргументы, пакеты и т. д. Иногда мы думаем что-то вроде: «И так понятно, что text – это текстовое поле. Зачем мудрить?» Однако взглянув на код или часть программного кода через неделю, две или месяц, натыкаемся на абракадабру, в которой непонятно что непонятно за что отвечает.

Допустим, вы написали небольшую графическую часть на Java. Что можно сказать о происходящем из представленного ниже программного кода?

setTitle(text1);
setSize(550,360);
setVisible(true);

text2.setEditable(false);

try {
    List text = Files.readAllLines(Paths.get("text.txt"));
    name = text.get(0)+":";
    name2.setText(name);
} catch (IOException e) {
    e.printStackTrace();
}

В коде происходит нечто странное. Давайте немного изменим его:

setTitle(title); // Здесь мы видим заголовок
setSize(550,360);
setVisible(true);

textAreaMessage.setEditable(false); //Здесь уже JTextArea, etc.

try {
    List mass = Files.readAllLines(Paths.get("text.txt"));
    name = mass.get(0)+":";
    labelName.setText(name);
} catch (IOException e) {
    e.printStackTrace();
}

Имя любой переменной, функции или класса должно отвечать на три вопроса: зачем это нужно, что делает и как используется. Выбор хороших имен поначалу требует времени, но в дальнейшем вы сэкономите намного больше. Тщательно подбирайте названия, и все, кто прочтет ваш код, будет вам благодарен.

Не бойтесь разбивать код на составляющие

Луис Салливан как-то сказал: «Форма следует за функцией».

Помните, что методы – это глаголы языка программирования, а классы – имена существительные. Не старайтесь делать методы огромными, включающими в себя все на свете. Будет гораздо понятнее, если вы разобьете класс на несколько методов. Так вы не запутаетесь в собственном коде, и другие люди его тоже поймут.

Небольшой пример-визуализация сказанного. Работа со слушателем:

buttonSave.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        buttonLogin();
    }
});

Просто выносим функцию нашей кнопки в отдельный метод:

protected void buttonLogin() {
    System.out.println("Вот так будет намного удобнее :)");
}

Комментирование программного кода

Это особенно важно, если вы новичок или пишете действительно большую программу, к которой придется возвращаться снова и снова. Если вы оставите код без единого комментария, рискуете не понять его спустя некоторое время.

Также это большой плюс при приеме на работу. Выполняя ТЗ работодателя, не забывайте комментировать код: так вы показываете свою серьезность и умение писать код, понятный для всех.

Комментировать можно строку или несколько строк, выделяя таким образом часть программного кода. Например, я всегда вывожу размещение элементов в своеобразный блок:

/*** Расположение элементов ***/
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

c.gridx = 0;
c.gridy = 0;
panel.add(labelQuestion, c);
c.gridx = 0;
c.gridy = 1;
panel.add(labelSpace, c);

А вот вариант объяснения одной из строк:

FileWriter writer;
try {
    writer = new FileWriter("text.txt", false);
    writer.write(textName.getText());
    writer.flush(); // Финализирует выходное состояние, очищая все буферы вывода
} catch (IOException e) {
    e.printStackTrace();
}

Удобно, правда? Работодатель или напарники по проекту будут того же мнения.

Минимализм vs информативность

Нет, от сокращения имен код не станет проще: это лишь сделает его запутанным и непонятным. Отсутствие комментариев также будет недостатком. Но есть еще ряд приемов, которые заметно уменьшат код. К таким приемам относятся:

Удаление лишних проверок и условий.
Избегание дублирования.
Умение пользоваться конкретным языком программирования.

С первым пунктом вроде все понятно, но давайте проясним. К ненужным проверкам относится в т. ч. проверка на null. Иногда это даже попахивает паранойей. Например:

obj = new Object();
...
if (obj != null) {
    obj.call();
}

А порой одно и то же условие проверяется несколько раз, словно что-то могло измениться без нашего вмешательства (разумеется, это не относится к коду, с которым действительно происходили соответствующие метаморфозы).

Дублирование – бич начинающих программистов. Из этого пункта вытекает и третий, ведь если человек знает все тонкости языка, он не станет намеренно увеличивать количество строк. Но странно то, что часто такие требования предъявляются именно новичкам, у которых просто недостаточно опыта, чтобы хорошо разобраться во всех тонкостях, например, ООП. Подобное исправляется лишь регулярной практикой.

Рекурсия – не панацея

Многие считают рекурсию лучшим средством для устранения всего лишнего. Если говорить о внешнем виде программного кода, это, несомненно, правда. Пример с факториалом:

public static void factorial() { // итерация
    int fact = 1;
    int n = 5;

    for (int i = 1; i<=n; i++){
        fact*=i;
        System.out.println(fact);
    }
}

static int factorial(int n){ //рекурсия
    int res;

    if (n == 1) return 1;
    res = fact(n-1)*n;
    return res;
}

Да, в этом случае код и там, и там маленький, но если прибавить кучу условий и строк – все изменится. Например, вот рекурсивное решение ханойской башни:

public static void hanoi(int n, String a, String b, String c){
    if (n == 1) System.out.println("#" + n + " " + a + " -> " + c);
    else {
        hanoi(n - 1, a, c, b);
        System.out.println("#" + n + " " + a + " -> " + c);
        hanoi(n - 1, b, a, c);
    }
}

А теперь вообразите, сколько строк выдаст новичок, столкнувшийся с ханойской башней и работающий только с итерацией. ))

Но не все так гладко. Попробуйте посчитать факториал большого числа. Вероятно, IDE зависнет, пытаясь переварить ваше решение, и это понятно: рекурсия «кушает» много памяти, так как метод каждый раз вызывает сам себя. Конечно, если в поставленной задаче рекурсия необходима (например, при обработке древовидных структур), использовать ее нужно, но ни в коем случае не злоупотреблять. Компактность-то она обеспечит, но что потом делать с памятью?

Не бойтесь перемен!

Здесь собраны очень простые рекомендации, о которых знает каждый, вот только далеко не каждый их использует. Допустим, вместо «многослойных» if-ов можно использовать оператор (x ? y : z).

Пример с if:

if (x) {
    var1 = y;
} else {
    var1 = z;
}

Пример с (x ? y : z):

var1 = x ? y : z;

Также не забывайте о существовании forEach(), который избавит вас от претензий в стиле «Многа букав»:

public static void forEach() {
    int [] mas = {1, 2, 3, 4, 5};
    for (int i : mas){
        System.out.println(i);
    }
}

Объединяйте вложенные if. Посмотрите, насколько проще становится код.

Было:

if (a) {
    if (b) {
        do_something();
    }
}

Стало:

if (a && b) {
    do_something();
}

Поговорим о боли под названием «try-catch»

Читаемость кода часто усугубляется повсеместными блоками try-catch, которые сильно портят «картинку». Кроме того, по мере чтения такого программного кода теряются цель и логика происходящего в нем. А все должно быть предельно понятным, особенно для стороннего человека. Правильно обрабатывать возможные ошибки – признак настоящего мастерства.

Да, блоки try-catch напрямую влияют на объем вашего кода. Да, полностью избавиться от этого нельзя, но можно свести к минимуму строки внутри такого блока, вынеся все остальные за его пределы. Но если такое дробление будет подразумевать создание еще большего количества try-catch – лучше обойтись без подобных экспериментов.

Еще исключение может обрабатываться где-нибудь внизу метода, не царапая глаз в середине кода.

Логирование

Не пренебрегайте лог-файлами! Эти «ребята» всегда помогут в создании и сопровождении вашего будущего ПО, ведь на поиски и обработку ошибок будет уходить гораздо меньше времени.

Вспомните ситуации, когда один из элементов приложения не работал или обрабатывал что-то непонятным образом, а что за причина – неизвестно. С лог-файлом время поиска проблемных участков сократится в разы.

Да, такие файлы предназначены для более сложных проектов, и в каких-нибудь Hello-world-программах просто не нужны. Но если вы разрабатываете приложение вдвоем или командой, либо это тестовое задание на допуск к собеседованию – займитесь логированием: интервьюер будет впечатлен, а команда – лишена необходимости переворачивать весь код вверх тормашками в поисках ошибки.

Тестирование

Юнит-тестирование (или модульное тестирование) – еще одна составляющая хорошего программного кода, которая заставит помучиться. Зато в итоге вы сможете запросто проверять на правильность отдельные модули.

Суть в том, что вы пишете тесты для каждой функции, которая не относится к тривиальным и составляет костяк программы. С юнит-тестами можно проверить, к чему приведут последующие изменения в коде.

Используйте бейджики качества кода

Часто в файлах README можно наблюдать небольшие иконки. Что же там делают данные графические элементы? Это бейджики, которые показывают, насколько хорош код. Зачастую используются либо перфекционистами, либо в серьезных проектах, но если даже незначительный по важности код прошел такую проверку – это огромный плюс.

Где получить бейджик? Для этого существуют специальные сервисы. Например, мне нравится Travis CI, предназначенный для сборки и тестирования ПО. Он использует в качестве хостинга GitHub, куда и коммитится проект, так что никаких проблем с привязкой Трэвиса к проекту нет.

Поначалу сложно понять, почему же сервис ругается и не пропускает код, но когда вы поймете, дальнейшее сотрудничество с сервисом пойдет как по маслу.



Мне нравится 0   Мне не нравится 0



Комментарии

Чтобы добавить видео с YouTube, нужно написать [@youtube=xxxxx] , где xxxxx – ID видео.


Комментарии: 0
Нет ни одного комментария.

Новое
Почему W-образные моторы уходят в прошлое, если они были лучше V-образных вчера, 09:02
Почему W-образные моторы уходят в прошлое, если они были лучше V-образных
20 простых и очень вкусных салатов с кальмарами 3 дня назад, 09:08
20 простых и очень вкусных салатов с кальмарами
Вирусы на Android: подробное руководство по обеспечению безопасности Пн 25.11.2024
Вирусы на Android: подробное руководство по обеспечению безопасности
15 интересных салатов со свежими огурцами Сб 23.11.2024
15 интересных салатов со свежими огурцами
Зал короля Артура оказался неолитическим загоном для скота Пн 18.11.2024
Зал короля Артура оказался неолитическим загоном для скота
15 действительно вкусных салатов с крабовыми палочками Сб 16.11.2024
15 действительно вкусных салатов с крабовыми палочками
Когда устал от алгоритмов: Ревью кода на собеседовании Вт 12.11.2024
Когда устал от алгоритмов: Ревью кода на собеседовании
Пн 11.11.2024
10 не самых очевидных причин, чтобы уволиться
Искусственный мозг против квантового компьютера: кто возьмет верх? Вс 10.11.2024
Искусственный мозг против квантового компьютера: кто возьмет верх?
10 лучших салатов с кукурузой Сб 09.11.2024
10 лучших салатов с кукурузой
Книги
Blazor in Action Вт 04.06.2024
Blazor in Action
Год: 2022
Security for Containers and Kubernetes Вт 28.05.2024
Security for Containers and Kubernetes
Год: 2023
Designing Data-Intensive Applications Вт 14.05.2024
Designing Data-Intensive Applications
Год: 2017
Fundamentals of Software Architecture Вт 07.05.2024
Fundamentals of Software Architecture
Год: 2020
Разработано на основе BlackNight CMS
Release v.2024-11-16
© 2000–2024 Blackball
Дизайн & программирование:
О сайтеРеклама
Visitors
Web-site performed by Sergey Drozdov
BlackballРекламаСтатистикаПоддержка
МузыкаПлейлистыКиноВидеоИгрыАудиоПрограммыСтатьиКартинкиЮморФорумДневник сайтаПрислать контентРекомендованное