diff --git a/sandbox/1/0__principy_chistogo_koda/article.md b/sandbox/1/0__principy_chistogo_koda/article.md new file mode 100644 index 0000000..53f2464 --- /dev/null +++ b/sandbox/1/0__principy_chistogo_koda/article.md @@ -0,0 +1,264 @@ +# Базовые принципы чистого кода + +### Введение + +Давайте поговорим о понятии чистого кода. Как вы кодируете? Это простой вопрос, но очень важный. Строите ли вы план, когда его пишете, или он рождается сам собой в процессе написания? Задумываетесь ли вы над названиями переменных, отступах и комментариях или пишете, как есть, оставляя вопросы стиля и читаемости до лучших времён? Ну и наконец, случалось ли вам при виде своего кода, написанного несколько месяцев назад, задаваться вопросом: “Что я здесь чёрт побери написал?” Если да, то этот урок для вас. +Чтобы продемонстрировать разницу между чистым и не очень чистым кодом, взгляните на следующие два примера. + +Листинг 1. Пример плохого кода + +```c +#include +int main(void){ +int a=0,c=666; +scanf("%d",&a); +for(int b=0;a!=c;){ +scanf("%d",&b); +if(b>a&&b!=666) +printf("%d",b); +a=b;} +return 0;} +``` + +Листинг 2. Пример чистого кода + +```c +#include + +int main(void) +{ + int EndNumber = 666; + int PreviousNumber = 0; + + scanf ("%d", &PreviousNumber); + + for(int CurrentNumber = 0; PreviousNumber != EndNumber;){ + + scanf ("%d", &CurrentNumber); + + if(CurrentNumber>PreviousNumber && CurrentNumber!=EndNumber){ + printf("%d ", CurrentNumber); + + } + PreviousNumber = CurrentNumber; + } + + + return 0; +} +``` + +Эти два кода работают совершенно одинаково и реализуют одну и ту же логику, однако написаны они по-разному: принимают последовательность чисел и выводят на экран только те числа, которые больше предыдущего введенного числа. Ввод числа 666 завершает последовательность. Можете запустить их в своей IDE и убедиться в этом. Чтобы превратить первый листинг во второй -- необходимо проделать работу с отступами и именами переменных. В этом уроке мы рассмотрим методы и техники, которые позволяют превратить нечитаемый код в чистый и понятный. + +Если бы вам дали чужой код и попросили его поправить, в каком бы из этих двух кодов было бы лучше разобраться и внести изменения? Вероятно, большинство разработчиков предпочтет работать со вторым примером. И теперь, когда мы увидели это воочию, давайте сформулируем для себя понятие чистого кода: + +=Чистый код= – это код, который легко понять, модифицировать и поддерживать. Он хорошо структурирован, имеет осмысленные имена переменных, которые отражают их назначение, и использует отступы для наглядного отображения структуры программы. Гради Буч говорит, что хороший код должен читаться как хорошо написанная проза. Вам не нужно каждый раз возвращаться на предыдущие строки с подобными вопросами “А что делает эта переменная?”, “А зачем здесь это выражение?”, “А что это за константа?”. + +Чтобы писать чистый код, необходимо знать базовые правила, которые широко приняты. Давайте возьмём код из листинга 1 и шаг за шагом приведём его в более читаемый и понятный вид. Наша задача – сделать так, чтобы код был понятен любому разработчику, который, взглянув на него, сразу поймёт его назначение и принцип работы. + +% **Важно!** +Всегда помните, что в первую очередь код должен быть понятен другим программистам. + +### Отступы - увидеть суть + +Правильная расстановка отступов позволяет разработчику быстро оценить общую структуру кода. Например, становится ясна вложенность циклов и область видимости переменных. В большинстве случаев рекомендуется смещать каждое вложение на 4 пробела вправо. Если есть второй уровень вложенности, то уже 8 пробелов. Обратите внимание на организацию отступов в листинге 3. + +Листинг 3. Пример отступов + +```c +#include + +int main() { + int x = 10; + + if (x > 5) { + printf("x больше 5\n"); + + if (x < 15) { + printf("x меньше 15\n"); + } + } else { + printf("x не больше 5\n"); + } + + return 0; +} +``` + +Посмотрите как организованы отступы. Внутри первого условия `if (x > 5)` вызов функции `printf` смещен на 4 пробела, так как он выполняется только при выполнении этого условия. Аналогично, второй оператор сравнения `if (x < 15)` также имеет отступ в 4 пробела. Вывод строки во втором `if` вложен как в первый, так и во второй оператор `if`, поэтому имеет отступ в 8 пробелов. + +Использование пустых строк позволяет быстро оценить общую структуру кода, которая для листинга 3 выглядит следующим образом: + +> Подключение библиотек +> +> Начало функции `main`, объявление переменных +> +> Блок сравнения +> +> Завершение функции `main` + +А теперь давайте возьмём наш первый листинг и применим к нему это правило. + +Листинг 4. Код листинга 1 с отступами + +```c +#include + +int main(void) +{ + int a=0; + + scanf ("%d", &a); + + for(int b = 0; a != 666;){ + + scanf ("%d", &b); + + if(b>a && b!=666){ + printf("%d ", b); + + } + a = b; + } + + return 0; +} +``` + +Уже гораздо солиднее, согласитесь. Теперь структура кода и вложенность операторов стали более наглядными. Переходим к следующему шагу. + +### Имена переменных – говорить на понятном языке + +Имя переменной должно отвечать на вопрос как она используется. Иными словами, в имени должен быть заключён смысл её существования. + +% **Важно!** +Если имя переменной не позволяет понять её смысл и назначение с первого взгляда, то стоит задуматься о его пересмотре. + +Посмотрите, например, на листинг ниже. + +Листинг 5. Пример плохого стиля именования переменных + +```c +#include + +int main() { +int s=0, d=0, h=0, m=0, hind=24, secinh=3600; + + scanf("%d", &s); + + d = s / (hind * secinh); + s %= (hind * secinh); + + h = s / secinh; + + printf("%d\n", d); + printf("%d\n", h); + + + return 0; +} +``` + +Тут без ста грамм не разберёшься. Чтобы понять, что делают переменные `d` и `s`, приходится постоянно обращаться к объявлениям `secinh` и `hind`. Здесь будет очень уместна цитата из книги Роберта Мартина «Чистый код»: нет худшей причины для выбора имени `c`, чем та, что имена `a` и `b` уже заняты. +Вы можете возразить: «`secinh` – хорошее имя, оно обозначает `sec in hour`, то есть количество секунд в одном часе!». Наверное, так действительно можно расшифровать. Но очевидное ли это название для человека, который первый раз смотрит на код? Что мешает программисту расписать переменную как `seconds_in_hour`? Конечно, название стало длиннее, но теперь полностью ясен смысл переменной и не возникает дополнительных вопросов. Код становится более читаемым и понятным, что значительно облегчает его поддержку и модификацию. + +% **Важно!** +Не бойтесь использовать длинные и описательные имена переменных. Важно, чтобы название максимально точно отражало смысл переменной и её роль в программе, даже если это приводит к увеличению длины кода. + +#### Стили +Ещё несколько слов об именовании переменных. Существуют два основных стиля именования переменных. + +1. *CamelCase*. В этом стиле, если переменная состоит из нескольких слов, каждое новое прописывается с заглавной буквы. Это название связано с тем, что заглавные буквы создают визуальное впечатление “горбов”, как у верблюда. При этом первое слово может как начинаться с заглавной, так и с прописной буквы. Вот несколько примеров: `DayInMonth`, `NumberTables`, `SecondsPassedFromFirstShot`. + +2. *snake_case*. В отличие от CamelCase, слова разделяются нижним подчёркиванием, и все буквы обычно строчные. Такое название связано с тем, что нижние подчеркивания визуально напоминают изгибы змеи. Вот также несколько примеров использования на тех же именах: `days_in_month`, `number_tables`, `second_passed_from_first_shot`. + +Выбор стиля именования – вопрос личных предпочтений или соглашений, принятых в команде. Важно придерживаться выбранного стиля последовательно во всем проекте. Хотя вы можете придумать свой способ именования переменных, рекомендуется придерживаться общепринятых стилей (CamelCase или snake_case), чтобы ваш код был понятен другим разработчикам + +Давайте исправим названия переменных в листинге 4. + + +Листинг 6. Код после наведения порядка в именах + +```c +#include + +int main(void) +{ + int EndNumber = 666; + int PreviousNumber = 0; + + scanf ("%d", &PreviousNumber); + + for(int CurrentNumber = 0; PreviousNumber != EndNumber;){ + + scanf ("%d", &CurrentNumber); + + if(CurrentNumber>PreviousNumber && CurrentNumber!=EndNumber){ + printf("%d ", CurrentNumber); + + } + PreviousNumber = CurrentNumber; + } + + + return 0; +} +``` + +В результате мы получили код, аналогичный листингу 2, демонстрируя, как применение простых правил (отступы и именование переменных) может значительно улучшить читаемость кода. Заметьте, что все числа были заменены переменными. Всегда избегайте применения “магических” чисел в коде. Вам они могут быть понятны, но другие разработчики могут задаться вопросом о смысле константы и лучше -- если у неё будет имя. + +Применив всего два простых правила -- правильные отступы и осмысленные имена переменных, мы превратили нечитаемый код в хорошо структурированный и понятный алгоритм. + +### Комментарии – говорить или молчать? + +Нельзя обойти стороной и такую важную сторону, как комментарии. Они необходимы, чтобы облегчить понимание кода для других разработчиков, которые будут его читать и поддерживать. Ранее комментарии играли важную роль, особенно в командной разработке. Разработчики часто добавляли в начало файла (“шапку”) информацию об авторе, версии кода и историю изменений. Это помогало координировать работу в команде и быстро отслеживать изменения. Однако с появлением систем контроля версий (например, Git) необходимость в этих “шапках” отпала. + +Тем не менее, комментарии по-прежнему полезны для объяснения сложных алгоритмов, неочевидных решений, ссылок на стандарты или обоснования нестандартного подхода. Однако комментарии, дублирующие очевидный код, не несут никакой пользы и только засоряют его. + +Листинг 7. Плохой пример использования комментариев. + +```c +#include + +int main() { + + int BatteryCapacityIn_mAh = 0, ConsuptionVoltage = 0, ConsuptionCurrentIn_mA = 0; // Объявление переменных + int TimeWorkingBattery_hours = 0, TimeWorkingBattery_minutes = 0; // Объявление переменных + + printf("Enter Capacity battery, consuption in V and mA: "); // Вывод текста на экран + scanf("%d %d %d", &BatteryCapacityIn_mAh, &ConsuptionVoltage, &ConsuptionCurrentIn_mA); // Ввод данных + + TimeWorkingBattery_hours = BatteryCapacityIn_mAh / (ConsuptionVoltage*ConsuptionCurrentIn_mA); // Вычисляем время работы в часах. Для этого ёмкость делим на расход + TimeWorkingBattery_minutes = (BatteryCapacityIn_mAh*60) / (ConsuptionVoltage*ConsuptionCurrentIn_mA); // Вычисляем время работы в минутах домножением на 60 + + printf ("\nWorking battery in hours: %d hours\nOR\nWorking battery in minutes: %d minutes\n\n", TimeWorkingBattery_hours, TimeWorkingBattery_minutes); // Вывод информации о времени работы батареи + return 0; +} +``` + +Здесь нет ни одного полезного комментария. Эти комментарии лишь повторяют очевидный код и не добавляют никакой новой информации, а наоборот, затрудняют чтение. Кроме того, комментарии написаны на кириллице, что может привести к проблемам с кодировкой и некорректному отображению на других компьютерах. Старайтесь писать комментарии на английском языке. + +% **Важно!** +Избегайте избыточных и тривиальных комментариев, которые не несут полезной информации и ухудшают читаемость кода. + +В целом, старайтесь минимизировать использование комментариев. Если часть кода требует подробного объяснения, возможно, лучше переписать её, чтобы сделать более понятной, чем оставлять сложный код и компенсировать это комментариями. + +Давайте подведём краткий итог и выделим основные =принципы чистого кода= + +1. Всегда соблюдайте отступы и вложенность кода. +2. Разделяйте смысловые части пустыми строками. +3. Уделяйте особое внимание именам переменных – они должны полностью описывать своё назначение. +4. Используйте именованные переменные-константы вместо “магических” чисел +5. Используйте комментарии только для объяснения сложных или неочевидных моментов. +6. Если код требует пояснений, предпочтительнее переписать его, чем добавлять комментарий. +7. Пишите комментарии на английском языке, чтобы код был понятен международному сообществу разработчиков. +8. Используйте Git для отслеживания изменений в коде. Это позволяет возвращаться к предыдущим версиям, отслеживать ошибки и работать над кодом совместно с другими разработчиками. + + + + +***Количество преспешников стилей*** + +*snake_case* *CamelCase* + +0 0 diff --git a/sandbox/1/0__principy_chistogo_koda/meta.json b/sandbox/1/0__principy_chistogo_koda/meta.json new file mode 100644 index 0000000..d5d531c --- /dev/null +++ b/sandbox/1/0__principy_chistogo_koda/meta.json @@ -0,0 +1,6 @@ +{ + "title": "Базовые принципы чистого кода", + "description": "", + "keywords": "", + "canonical_link": "https://youngcoder.ru/lessons/%N%/%FOLDER0_NAME%" +} \ No newline at end of file diff --git a/sandbox/1/0__principy_chistogo_koda/practice.md b/sandbox/1/0__principy_chistogo_koda/practice.md new file mode 100644 index 0000000..31ae1ce --- /dev/null +++ b/sandbox/1/0__principy_chistogo_koda/practice.md @@ -0,0 +1,3 @@ +### Исследовательские задачи для хакеров + +- Почитайте книгу А.В. Столярова "Оформление программного кода". Посмотрите, какие ещё следует соблюдать правила при именовании переменных. diff --git a/sandbox/1/0__principy_chistogo_koda/reference.md b/sandbox/1/0__principy_chistogo_koda/reference.md new file mode 100644 index 0000000..48fc8d6 --- /dev/null +++ b/sandbox/1/0__principy_chistogo_koda/reference.md @@ -0,0 +1,4 @@ +## Дополнительные материалы + +1. Посмотрите на то, как расположены фигурные скобки в листинге 3. Это, один из стилей оформления фигурных скобок, называемый K&R - по инициалам авторов книги Основы программирования на Си. (Kernighan и Ritchie). Поищите информацию о других стилях и напишите в комментариях какой вам понравился больше. +2. Напишите в комментариях, какой стиль именования переменных вам больше понравится, а мы в этой лекции будем вести счёт. diff --git a/sandbox/1/index.md b/sandbox/1/index.md new file mode 100644 index 0000000..fd59dd0 --- /dev/null +++ b/sandbox/1/index.md @@ -0,0 +1,5 @@ +# Базовые принципы чистого кода + +Этот урок охватывает основные принципы и правила написания чистого кода. +Вы узнаете, как сделать ваш код более читаемым, поддерживаемым и эффективным, применяя простые, но мощные техники, такие как правильные отступы, осмысленные имена переменных и умеренное использование комментариев. +Урок содержит практические примеры и рекомендации, которые помогут вам писать код, которым будет приятно делиться и с которым легко работать. \ No newline at end of file diff --git a/sandbox/1/meta.json b/sandbox/1/meta.json new file mode 100644 index 0000000..276daa7 --- /dev/null +++ b/sandbox/1/meta.json @@ -0,0 +1,7 @@ +{ + "title": "Урок(?): Базовые принципы чистого кода", + "description": "В данном уроке (?) рассматриваются основные принципы чистого кода, которые помогут вам писать более читаемый, понятный и легко поддерживаемый код.", + "keywords": "Чистый код, рефакторинг, красивый код, имена переменных", + "canonical_link": "https://youngcoder.ru/man/chistyi_kod", + "has_glory_hall": false +} \ No newline at end of file