Как найти вонючие части вашего кода [Часть XVII]
21 апреля 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)
- [Часть XV] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xv)
- [Часть XVI] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xvi)
Давай продолжим...
Код Запах 81 - Результат
результат = ???
TL;DR: Всегда используйте хорошие имена. Результат - это всегда очень плохое имя.
Проблемы
- Читабельность
Решения
- Переименуйте результат.
- Если вы не знаете, как ее назвать, просто назовите переменную тем же именем, что и последний вызов функции.
- Не используйте IDE без автоматического рефакторинга.
Образец кода
Неправильный
```javascript
переменный результат;
результат = lastBlockchainBlock();
// Много вызовов функций
addBlockAfter (результат);
Верно
```javascript
вар lastBlockchainBlock;
lastBlockchainBlock = найтиlastBlockchainBlock();
// Много вызовов функций
// мы должны реорганизовать их, чтобы минимизировать пространство
// между определением переменной и использованием
addBlockAfter (lastBlockchainBlock);
Обнаружение
Мы должны запретить, чтобы слово result было именем переменной.
Теги
- Читабельность
Вывод
Результат является примером общих и бессмысленных имен.
Рефакторинг дешев и безопасен.
Всегда оставляйте палаточный лагерь чище, чем вы его нашли.
Когда найдешь беспорядок на земле, убери его, неважно, кто это сделал. Ваша задача — всегда оставлять землю чище для следующих отдыхающих.
Связи
[Code Smell 79 — TheResult] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xvi)
Больше информации
- [Что в имени? Часть I: Реабилитация] (https://hackernoon.com/what-exactly-is-a-name-rehab-part-ii-4st3uph).
Кредиты
Код как юмор. Когда приходится объяснять, это плохо.
Кори Хаус
Code Smell 82 — тесты нарушают инкапсуляцию
Объекты работают нормально и выполняют бизнес-цели. Но нам нужно их протестировать. Давайте сломаем их.
TL;DR: не пишите методы только для того, чтобы их можно было использовать в тестах.
Проблемы
- Нарушение инкапсуляции.
- Плохие интерфейсы
- Связь
Решения
- Не нарушайте инкапсуляцию.
- Тест должен находиться под полным контролем.
- Если вы не можете контролировать свой объект, вы связаны. Разъедините их!
Образец кода
Неправильный
```php
класс Палач {
частный $wordToGuess;
функция __construct () {
$this->wordToGuess = getRandomWord();
//Тест не контролирует это
публичная функция getWordToGuess(): строка {
вернуть $this->wordToGuess;
//К сожалению, нам нужно раскрыть это
класс HangmanTest расширяет TestCase {
функция test01WordIsGuessed() {
$hangmanGame = новый палач();
$this->assertEquals('тесты', $hangmanGame->wordToGuess());
//как мы можем убедиться, что слово угадано?
Верно
```php
класс Палач {
частный $wordToGuess;
функция __construct(WordRandomizer $wordRandomizer) {
$this->wordToGuess = $wordRandomizer->newRandomWord();
класс MockRandomizer реализует WordRandomizer {
функция newRandomWord(): строка {
вернуть «тесты»;
класс HangmanTest расширяет TestCase {
функция test01WordIsGuessed() {
$hangmanGame = новый палач (новый MockRandomizer());
//У нас полный контроль!
$this->assertFalse($hangmanGame->wordWasGuessed());
$hangmanGame->играть('t');
$this->assertFalse($hangmanGame->wordWasGuessed());
$hangmanGame->play('e');
$this->assertFalse($hangmanGame->wordWasGuessed());
$hangmanGame->играть('s');
$this->assertTrue($hangmanGame->wordWasGuessed());
//Мы просто тестируем поведение
Обнаружение
Это дизайнерский запах.
Мы можем обнаружить, что нам нужен метод только для проверки.
Теги
- Сокрытие информации
Вывод
Тесты белого ящика хрупки. Они проверяют реализацию, а не поведение.
Связи
[Code Smell 52 — Fragile Tests] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xi-sit35t1)
[Code Smell 28 — Setters] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-vi-cmj31om)
Больше информации
- [Должен ли я тестировать частные методы] (http://shoulditestprivatemethods.com/)
Кредиты
На создание этого запаха вдохновил @Rodrigo
[Твиттер] (https://twitter.com/1408032157629485056)
Ничто не делает систему более гибкой, чем набор тестов.
Роберт Мартин
Code Smell 83 - Переназначение переменных
Повторное использование переменных — это то, что мы видим в больших кусках кода.
TL;DR: не используйте повторно имена переменных. Вы нарушаете удобочитаемость и шансы на рефакторинг и ничего не получаете, кроме лени.
Проблемы
- Читабельность
- Шансы на рефакторинг
- Пропущенная оптимизация
- Изменчивость
- Сбор мусора Упущенные возможности
Решения
- Определите, используйте и удалите переменные.
- Держите переменные Definition, Usage и Destroy короткими.
Образец кода
Неправильный
```питон
предмет класса:
def init(я, имя):
self.name = имя
деф налогиCharged(self):
вернуть 1;
класс Деньги:
проходят
lastPurchase = Товар('Газировка');
Сделайте что-нибудь с покупкой
taxAmount = lastPurchase.taxesCharged();
Много вещей, связанных с покупкой
Я пью газировку
Я не могу извлечь метод снизу без передачи
бесполезный параметр lastPurchase
несколько часов спустя..
lastPurchase = Товар('Виски');
Я покупаю еще выпить
taxAmount += lastPurchase.taxesCharged();
Верно
```питон
предмет класса:
def init(я, имя):
self.name = имя
деф налогиCharged(self):
вернуть 1;
класс Деньги:
проходят
деф купитьСуппер():
supperPurchase = Предмет('Газировка');
Сделайте что-нибудь с покупкой
Много вещей, связанных с покупкой
Я пью газировку
вернуть ужинПокупка;
деф купитьНапитки():
Я смог извлечь метод!
несколько часов спустя..
drinkPurchase = Товар('Виски');
Я покупаю еще выпить
возврат напитковПокупка;
taxAmount = buySupper().taxesCharged() + buyDrinks().taxesCharged();
Обнаружение
Многие линтеры могут предостеречь нас от повторного использования переменных
Теги
- Читабельность
Вывод
Повторное использование переменных — это неконтекстная подсказка копирования и вставки.
Связи
[Code Smell 03 — Слишком длинные функции] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-i-xqz3evd)
Больше информации
- [Злая сила мутантов] (https://hackernoon.com/is-it-crystal-clear-for-everybody-that-a-date-should-not-mutate-wuoy3z03)
- [Обмен стеками] (https://softwareengineering.stackexchange.com/questions/115520/should-i-reuse-variables)
Кредиты
Фото [Робби Маккалоу] (https://unsplash.com/@mybbor) на [Unsplash] (https://unsplash.com/s/photos/spiral)
[Твиттер] (https://twitter.com/1414832436547133440)
Как бы вы на это ни смотрели (сухо или лень), идея одна и та же: сделать вашу программу гибкой. Когда придут перемены (а так бывает всегда), вам будет намного легче меняться вместе с ними.
Крис Пайн
Код Запах 84 - Максимум < Мин (Javascript)
Некоторые функции работают не так, как ожидалось. К сожалению, большинство программистов их принимают.
TL;DR: не доверяйте функциям max() и min(). Просто игнорируйте их.
Проблемы
- Принцип наименьшего удивления
- Биекция Нарушение.
- Неожиданные результаты
Решения
- Используйте зрелые языки.
- Избегайте функций max() и min().
- Тщательно моделируйте Бесконечность.
Образец кода
Неправильный
```javascript
console.log(Math.max() > Math.min());
// возвращает ложь
console.log(Math.max());
//возвращает -бесконечно
Верно
```javascript
console.log(Math.max() > Math.min());
console.log(Math.max());
//возвращает Исключение. Передано недостаточно аргументов.
//Max требует хотя бы один аргумент
Обнаружение
Эти функции принадлежат стандартной математической библиотеке. Поэтому их нелегко избежать.
Мы можем заблокировать их на наших линтерах.
Теги
- Джаваскрипт
Вывод
Нам нужно быть очень осторожными, используя функции, которые нарушают концепции реального мира с помощью языковых уловок.
Связи
[Code Smell 69 — Big Bang (нелепые кастинги JavaScript)] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiv)
Больше информации
- [Принцип биекции] (https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp)
- [MAPPER] (https://hackernoon.com/what-is-wrong-with-software-uh8j3y7k)
Кредиты
Фото Крис Барон на Unsplash
Вдохновленный @@Oliver Jumpertz
[Твиттер] (https://twitter.com/1416798870747684864)
Программирование сегодня — это гонка между инженерами-программистами, стремящимися создавать большие и лучшие программы, защищающие от идиотов, и Вселенной, пытающейся производить больших и лучших идиотов. Пока Вселенная побеждает.
Рик Кук
Код Запах 85 - И Функции
Не делайте больше, чем требуется.
TL;DR: если вам не нужна атомарность, не выполняйте более одной задачи.
Проблемы
- Связь
- Нарушение принципа единой ответственности
- Читабельность
- Низкая сплоченность
- Тестируемость
Решения
- Сломать функцию
Образец кода
Неправильный
```питон
защита fetch_and_display_personnel():
данные = # ...
для человека в данных:
печать (человек)
Верно
```питон
защита fetch_personnel():
возврат # ...
определение display_personnel (данные):
для человека в данных:
печать (человек)
Обнаружение
Функции, включающие «и», являются кандидатами. Однако нам нужно тщательно их проверять, так как могут быть ложные срабатывания.
Теги
- Читабельность
- Именование
Вывод
Мы должны избегать делать больше, чем необходимо, и наши функции должны быть минимальными и атомарными.
Больше информации
- [Что такое имя — Часть II Реабилитация] (https://hackernoon.com/what-exactly-is-a-name-rehab-part-ii-4st3uph)
Кредиты
Этот запах вдохновлен
[Твиттер] (https://twitter.com/1428027665529769985)
Если для объяснения того, что вы делаете, требуется больше одного предложения, это почти всегда является признаком того, что то, что вы делаете, слишком сложно.
Сэм Альтман
И это пока все…
В следующей статье мы расскажем еще о 5 запахах кода!
Оригинал