Как найти вонючие части вашего кода [Часть XV]
23 марта 2022 г.Бесконечный код пахнет!
Мы видим несколько симптомов и ситуаций, которые заставляют усомниться в качестве нашего развития.
Давайте рассмотрим некоторые возможные решения.
Большинство этих запахов — просто намеки на то, что что-то может быть не так. Это не жесткие правила.
Запахи предыдущего кода
- [Часть I] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd)
- [Часть II] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ii-o96s3wl4)
- [Часть III] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv)
- [Часть IV] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iv-7sc3w8n)
- [Часть V] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-v-evj3zs9)
- [Часть VI] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vi-cmj31om)
- [Часть VII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vii-8dk31x0)
- [Часть VIII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-viii-8mn3352)
- [Часть IX] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ix-7rr33ol)
- [Часть X] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-x-i7r34uj)
- [Часть XI] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xi-sit35t1)
- [Часть XII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xii)
- [Часть XIII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiii)
- [Часть XIV] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiv)
Давай продолжим...
Code Smell 71 - Волшебные поплавки, замаскированные под десятичные дроби
TL;DR Не доверяйте числам на незрелых языках, таких как JavaScript.
Проблемы
- Принцип наименьшего удивления Нарушение
- [Случайная сложность] (https://hackernoon.com/there-are-no-silver-bullets-for-this-werewolf-2t213woi)
- Неправильные десятичные представления.
Решения
- Выберите зрелые языки.
- Представьте [десятичные числа десятичными знаками] (https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp).
Образец кода
Неправильно
```javascript
console.log(0,2 + 0,1)
// 0.30000000000000004
// Мы добавляем два десятичных числа
// 2/10 + 1/10
// Результат должен быть 3/10, как мы учили в школе
Верно
```javascript
класс Десятичный {
конструктор (числитель) {
this.numerator = числитель;
плюс (другой десятичный) {
вернуть новый десятичный (этот.нумератор + другойдесятичный.нумератор);
нанизывать() {
вернуть «0». + этот.числитель;
console.log((новый десятичный(2).плюс(новый десятичный(1))).toString());
// 0,3
// Мы можем представить числа с помощью класса Decimal (сохраняя только числитель)
// или с общим классом Fraction (хранящим как числитель, так и знаменатель)
Обнаружение
Поскольку это особенность языка, ее трудно обнаружить. Мы можем попросить наши линтеры помешать нам таким образом манипулировать числами.
Теги
- JavaScript
- Преждевременная оптимизация
Заключение
Моим первым языком программирования был [Commodore 64] (https://en.wikipedia.org/wiki/Commodore_64) в 1985 году.
Я был очень удивлен, обнаружив, что 1+1+1 не всегда равно 3. Затем они ввели целочисленные типы.
JavaScript на 30 лет моложе, и у него те же проблемы незрелости.
Больше информации
Вот техническое (и случайное) объяснение:
https://blog.pankajtanwar.in/do-you-know-01-02-03-in-javascript-here-is-why
Пожалуйста, не спорьте, говоря, что это нормально и ожидаемо, поскольку это двоичное представление.
Эти числа являются десятичными, мы должны представлять их как десятичные числа. Если вы думаете, что представление их в виде чисел с плавающей запятой значительно повышает производительность, вы ошибаетесь. Преждевременная оптимизация — корень всех зол.
[Стандарт с плавающей запятой — 83 страницы] (https://en.wikipedia.org/wiki/IEEE_754)
Цель вычислений — понимание, а не числа — Ричард Хэмминг
Код Запах 72 - Коды возврата
API, коды возврата, язык программирования C, мы все были там.
TL;DR: не возвращайте коды самому себе. Поднимите исключения.
Проблемы
- Загрязнение кода
- Устаревшая документация
- Связь со случайными кодами.
- Функциональная логика загрязнена.
Решения
- Измените идентификаторы и верните общие исключения.
- Отличайте «Счастливый путь» от «Исключительного пути».
Образец кода
Неправильно
```javascript
функция createSomething(аргументы) {
//Магическое создание
успех = ложь; //мы потерпели неудачу
//Нам не удалось создать
если (! успех) {
вернуть {
объект: ноль,
код ошибки: 403,
errorDescription: «У нас не было разрешения на создание...»
вернуть {
объект: созданныйОбъект,
код ошибки: 400,
описание ошибки: ''
var myObject = createSomething('аргумент');
если (мойОбъект.errorCode != 400) {
console.log(myObject.errorCode + ' ' + myObject.errorDescription)
//но myObject не содержит My Object, а реализует
//и случайный массив
//с этого момента мне нужно запомнить это
Верно
```javascript
функция createSomething(аргументы) {
//Магическое создание
успех = ложь; //мы потерпели неудачу
//Нам не удалось создать
если (! успех) {
throw new Error('У нас нет прав на создание...');
вернуть созданныйОбъект;
пытаться {
var myObject = createSomething('аргумент');
//нет IFS, просто счастливый путь
} поймать (исключение) {
//иметь дело с этим!
console.log(исключение.сообщение);
// myObject содержит мой ожидаемый объект
Обнаружение
Мы можем научить наши линтеры находить шаблоны целочисленных и строковых возвратов в сочетании с проверками if и return.
Теги
- Исключения
Заключение
- Идентификаторы и коды являются внешними идентификаторами.
- Они полезны, когда вам нужно взаимодействовать с внешней системой (например, API Rest).
- Мы не должны использовать их в наших собственных системах и наших собственных внутренних API.
- Создавать и вызывать общие исключения.
- Создавайте определенные исключения только в том случае, если вы готовы их обрабатывать, и они имеют особое поведение.
- Не создавайте [анемичные] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd) исключения.
- Избегайте [незрелых и преждевременно оптимизированных языков] (https://golangdocs.com/errors-exception-handling-in-golang), предпочитая коды возврата.
Больше информации
https://hackernoon.com/how-to-get-rid-of-annoying-ifs-forever-zuh3zlo
http://nicolecarpenter.github.io/2016/03/15/clean-code-chapter-7-error-handling.html
Обработка ошибок важна, но если она затемняет логику, значит, это неправильно — Роберт Мартин
Код Запах 73 - Исключения для ожидаемых случаев
Исключения составляют удобные Gotos и флаги. Давайте оскорбим их.
TL;DR: не используйте исключения для управления потоком.
Проблемы
- Читабельность
- Нарушение принципа наименьшего удивления.
Решения
- Используйте исключения только для непредвиденных ситуаций.
- Исключения обрабатывают нарушения контракта. Прочтите договор.
Образец кода
Неправильно
```java
пытаться {
для (целое я = 0;; я++)
массив[i]++;
} поймать (ArrayIndexOutOfBoundsException e) {}
// Бесконечный цикл без конечного условия
Верно
```java
for (int index = 0; index < array.length; index++)
массив[индекс]++;
//index < array.length прерывает выполнение
Обнаружение
Это смысловой запах. Если мы не будем использовать линтеры машинного обучения, будет очень сложно найти ошибки.
Теги
- Читабельность
Заключение
Исключения удобны, и мы определенно должны использовать их вместо возвращаемых кодов.
Граница между правильным и неправильным использованием размыта, как и многие другие принципы дизайна.
Связи
[Code Smell 72 — Коды возврата] (https://maximilianocontieri.com/code-smell-72-return-codes)
Больше информации
- [Не используйте исключения для управления потоком] (https://wiki.c2.com/?DontUseExceptionsForFlowControl)
- [Зона Java] (https://dzone.com/articles/exceptions-as-controlflow-in-java)
- [Обмен стеками] (https://softwareengineering.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so-why)
- [Переполнение стека] (https://stackoverflow.com/questions/729379/why-not-use-exceptions-as-regular-flow-of-control)
При отладке новички вставляют корректирующий код; эксперты удаляют дефектный код - Ричард Паттис
Код Запах 74 - Пустые строки
Разрушение кода для удобства чтения требует рефакторинга.
TL;DR Не добавляйте в методы пустые строки. Извлеките их!
Проблемы
- Читабельность
- Целовать
- Низкое повторное использование
Решения
- Метод извлечения
- Рефакторинг
- Удалите ненужные строки.
Образец кода
Неправильно
```php
функция перевода файла () {
$this->buildFilename();
$это->прочитатьФайл();
$this->assertFileContentsAreOk();
//Ещё много строк
//Пустое место для приостановки определения
$this->translateHiperLinks();
$this->translateMetadata();
$this->translatePlainText();
//Еще одно пустое место
$this->генерироватьстатистику();
$this->saveFileContents();
//Намного больше строк
Верно
```php
функция перевода файла () {
$this->readFileToMemoy();
$this->translateContents();
$this->saveFileContents();
Обнаружение
Это запах политики. Каждый линтер может обнаружить пустые строки и предупредить нас.
Теги
- Читабельность
- Длинные методы
Заключение
Пустые строки безвредны, но показывают нам возможность разбить код на маленькие шаги.
Если вы ломаете свой код комментариями, это тоже запах кода, требующий рефакторинга.
Разгадывать тайны убийства — это нормально, но код разгадывать не нужно. Вы должны уметь это читать - Стив МакКоннелл
Code Smell 75 — Комментарии внутри метода
- Комментарии часто являются запахом кода. Вставка их внутрь метода требует срочного рефакторинга.*
TL;DR Не добавляйте комментарии внутри ваших методов. Извлекайте их и оставляйте декларативные комментарии только для неочевидных дизайнерских решений.
Проблемы
- Читабельность
- Целовать
- Низкое повторное использование
- Плохая документация
Решения
- Метод извлечения
- Рефакторинг
- Удалите недекларативные комментарии.
Образец кода
Неправильно
```javascript
функция recoveryFromGrief() {
// Стадия отказа
поглотитьплохие новости();
setNumbAsProtectiveState();
startToRiseEmotions();
чувствовать печаль();
// Стадия гнева
маскаРеалистичные эффекты();
прямой гнев на других людей ();
винить других();
получить иррациональное();
// стадия торга
чувствовать себя уязвимым();
сожалеть();
спроситьПочемуСебя();
dreamOfAlternativeWhatIfScenarios();
отложитьПечаль();
// стадия депрессии
Соблюдай тишину();
получить переполнение();
быть в замешательстве();
// этап приемки
принять то, что случилось();
смотреть в будущее();
реконструировать и пройти();
Верно
```javascript
функция recoveryFromGrief() {
Стадия отказа();
Стадия гнева();
Стадия торга();
стадия депрессии();
Стадия принятия();
функция DenialStage() {
поглотитьплохие новости();
setNumbAsProtectiveState();
startToRiseEmotions();
чувствовать печаль();
функция angerStage () {
маскаРеалистичные эффекты();
прямой гнев на других людей ();
винить других();
получить иррациональное();
функция торгаStage() {
чувствовать себя уязвимым();
сожалеть();
спроситьПочемуСебя();
dreamOfAlternativeWhatIfScenarios();
отложитьПечаль();
функция депрессииСтадия() {
Соблюдай тишину();
получить переполнение();
быть в замешательстве();
функция acceptStage() {
принять то, что случилось();
смотреть в будущее();
реконструировать и пройти();
Обнаружение
Это запах политики. Каждый линтер умеет обнаруживать комментарии не в первой строке и предупреждать нас.
Теги
- Читабельность
- Длинные методы
- Комментарии
Заключение
Комментарии — это запах кода. Если вам нужно задокументировать проектное решение, вы должны сделать это до фактического кода метода.
Связи
[Code Smell 03 — Слишком длинные функции] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd)
[Code Smell 74 — Пустые строки] (https://maximilianocontieri.com/code-smell-74-empty-lines)
[Code Smell 05 — Нарушители комментариев] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd)
Не ведитесь на комментарии, они могут ввести в заблуждение: отлаживайте только код - Дэйв Сторер
И это пока все…
В следующей статье мы расскажем еще о 5 запахах кода!
Оригинал