Как найти вонючие части вашего кода [Часть XIX]
24 мая 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)
- [Часть XVII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xvii)
- [Часть XVIII] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xviii)
Давай продолжим...
Code Smell 91 — тестовые утверждения без описания
- Мы большие поклонники xUnit. Но нам наплевать на программистов*
TL;DR: используйте утверждения с декларативными описаниями.
Проблемы
- Читабельность
- Жесткая отладка
- Пустая трата времени
Решения
- Поместите красивое описательное утверждение
- Делитесь руководствами по решению проблем
Образец кода
Неправильный
```php
общедоступная функция testNoNewStarsAppeared(): недействительна
$expectedStars = $this->историческийStarsOnFrame();
$observedStars = $this->starsFromObservation();
//Эти предложения получают очень большую коллекцию
$this->assertEquals($expectedStars, $observedStars);
// Если что-то не получится, у нас будет очень тяжелое время отладки
Верно
```php
общедоступная функция testNoNewStarsAppeared(): недействительна
$expectedStars = $this->историческийStarsOnFrame();
$observedStars = $this->starsFromObservation();
//Эти предложения получают очень большую коллекцию
$newStars = array_diff($expectedStars, $observedStars);
$this->assertEquals($expectedStars, $observedStars,
«Есть новые звезды». print_r($newStars,правда));
//Теперь мы можем ТОЧНО увидеть, почему утверждение не удалось с четким и
// Декларативное сообщение
Обнаружение
Поскольку assert и assertDescription — разные функции, мы можем настроить наши политики в пользу последней.
Теги
- Тестовые запахи
Вывод
Уважительно относитесь к читателю своих утверждений.
Это может быть даже ты сам!
Больше информации
- [XUnit: Assert Description Deprecation] (https://github.com/xunit/xunit/issues/350)
Кредиты
Фотография Startaê Team на Unsplash
Всегда кодируйте так, как будто парень, который в конечном итоге будет поддерживать ваш код, будет жестоким психопатом, который знает, где вы живете.
Джон Вудс
Code Smell 92 - Имена изолированных подклассов
Если ваши классы являются глобальными, используйте полные имена
TL;DR: не используйте аббревиатуры в подклассах
Проблемы
- Читабельность
- Ошибки
Решения
- Переименуйте свои классы, чтобы обеспечить контекст
- Используйте модули, пространства имен или полные имена
Образец кода
Неправильный
```java
абстрактный класс PerserveranceDirection {
класс North расширяет PerserveranceDirection {}
класс Восток расширяет PerserveranceDirection {}
класс West расширяет PerserveranceDirection {}
класс South расширяет PerserveranceDirection {}
//Подклассы имеют короткие имена и не имеют смысла вне иерархии
//Если мы ссылаемся на восток, мы можем ошибочно принять его за сторону света
Верно
```java
абстрактный класс PerserveranceDirection {
класс PerserveranceDirectionNorth расширяет PerserveranceDirection {}
класс PerserveranceDirectionEast расширяет PerserveranceDirection {}
класс PerserveranceDirectionWest расширяет PerserveranceDirection {}
класс PerserveranceDirectionSouth расширяет PerserveranceDirection {}
//Подклассы имеют полные имена
Обнаружение
Автоматическое обнаружение — непростая задача. Мы могли бы применять локальные политики именования для подклассов.
Теги
- Именование
Вывод
Выбирайте имена с умом.
Если ваш язык поддерживает это, используйте модули, пространства имен и локальные области видимости.
Связи
[Code Smell 11 — Подклассификация повторного использования кода] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv)
Больше информации
- [Что в имени?] (https://hackernoon.com/what-exactly-is-a-name-the-quest-part-i-fmw3udc)
- [MAPPER] (https://hackernoon.com/the-one-and-only-software-design-principle-1x983ylp)
Кредиты
Фото [Эдварда Александра Рёлваага] (https://unsplash.com/@edvardr) на [Unsplash] (https://unsplash.com/s/photos/hierarchy)
Основное оружие программиста в нескончаемой битве с медленной системой — изменение внутримодульной структуры. Нашей первой реакцией должна быть реорганизация структур данных модулей.
Фредерик П. Брукс
Код Запах 93 - Пришлите мне что-нибудь
Волшебные функции, которые могут принимать множество разных (и не полиморфных) аргументов
TL;DR: создайте четкий контракт. Ожидайте только один протокол.
Проблемы
- Нарушение принципа Fail Fast
- Ошибка обрезки
- Читабельность
- [Если загрязняет] (https://hackernoon.com/how-to-get-rid-of-annoying-ifs-forever-zuh3zlo)
- [Нули] (https://hackernoon.com/null-the-billion-dollar-mistake-8t5z32d6)
- Плохая сплоченность
Решения
- Возьмите только один «вид» входных данных
- Аргументы должны придерживаться единого протокола.
Образец кода
Неправильный
```php
функция parseArguments($arguments) {
$аргументы = $аргументы ?: ноль;
//Всегда ошибка на миллиард долларов
если (is_empty($arguments)) {
$this->arguments = http_build_query($_REQUEST);
//Глобальная связь и побочные эффекты
} elseif (is_array($arguments)) {
$this->arguments = http_build_query($arguments);
} elseif (!$arguments) { //нуль без маски
$this->аргументы = ноль;
} еще {
$this->arguments = (string)$arguments;
Верно
```php
функция parseArguments (массив аргументов $) {
$this->аргументы = $аргументы;
//намного чище, не так ли?
Обнаружение
Мы можем обнаружить такие методы, когда они делают разные вещи, запрашивая аргумент kind
Теги
- Если загрязнитель
Вывод
Магические заклинания и гибкость имеют свою цену. Они кладут мусор под ковер и нарушают принцип отказоустойчивости.
Связи
[Code Smell 69 — Big Bang (нелепые кастинги JavaScript)] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiv)
[Code Smell 06 — Too Clever Programmer] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-ii-o96s3wl4)
[Code Smell 12 — Null] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv)
Кредиты
Фотография Hennie Stander на Unsplash
Ссылочная прозрачность — очень желательное свойство: она подразумевает, что функции постоянно дают одни и те же результаты при одних и тех же входных данных, независимо от того, где и когда они вызываются.
Эдвард Гарсон
Код Запах 94 - Слишком много импорта
- Если ваш класс зависит от слишком многих других, он будет связанным и хрупким. Длинный список импорта — хороший показатель.*
TL;DR: не импортируйте слишком много.
Проблемы
- Связь
- Нарушение принципа единой ответственности
- Низкая сплоченность
Решения
- Прервать урок
- Скрыть промежуточную случайную реализацию
Образец кода
Неправильный
```java
импортировать java.util.LinkedList;
импортировать java.persistence;
импортировать исключение java.util.ConcurrentModificationException;
импортировать java.util.Iterator;
импортировать java.util.LinkedList;
импортировать java.util.List;
импортировать java.util.ListIterator;
импортировать java.util.NoSuchElementException
импортировать java.util.Queue;
импортировать org.fermi.common.util.ClassUtil;
импортировать org.fermi.Data;
// Мы полагаемся на слишком много библиотек
демонстрация публичного класса {
public static void main(String[] args) {
Верно
```java
импортировать org.fermi.domainModel;
импортировать org.fermi.workflow;
//Мы полагаемся на несколько библиотек
//и прячем их реализацию
//Так что, возможно, транзитивный импорт такой же
//но мы не нарушаем инкапсуляцию
демонстрация публичного класса {
public static void main(String[] args) {
Обнаружение
Мы можем установить порог предупреждения для наших линтеров.
Теги
- Связь
- Волновой эффект
Вывод
Нам нужно думать о зависимостях при создании наших решений, чтобы минимизировать волновой эффект.
Связи
[Code Smell 61 — Связь с классами] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xiii)
Больше информации
- [Связь: единственная проблема проектирования программного обеспечения] (https://hackernoon.com/coupling-the-one-and-only-software-designing-problem-9z5a321h)
- [Пространства имен в Википедии] (https://en.wikipedia.org/wiki/Пространство имен)
Кредиты
Фото Зденек Махачек на Unsplash
[Твиттер] (https://twitter.com/1447623706767921153)
Дураки игнорируют сложность. Прагматики страдают. Некоторые могут этого избежать. Гении убирают.
Алан Перлис
Код Запах 95 - Преждевременная классификация
- Мы слишком обобщаем. Мы не должны создавать абстракции, пока не увидим достаточно конкретики.*
TL;DR: Не гадайте, что принесет вам будущее.
Контекст
Аристотелевская классификация - большая проблема в информатике.
Мы склонны классифицировать и называть вещи прежде чем собрать достаточно знаний и контекста.
Проблемы
- Футурология
- Плохой дизайн
Решения
- Дождаться конкрементов
- Рефакторинг поздно
Образец кода
Неправильный
```java
класс Прямоугольник
внутренняя длина;
инт широта;
внутренняя область ()
обратная длина * ширина;
//Мы создаем преждевременную абстракцию
// И неправильное использование отношения is-a, поскольку Square "является" Rectangle
класс Square расширяет прямоугольник
внутренняя длина;
внутренняя область ()
возвращаемая длина * длина;
Верно
```java
класс Прямоугольник
внутренняя длина;
инт широта;
внутренняя область ()
обратная длина * ширина;
класс Площадь
внутренняя длина;
внутренняя область ()
возвращаемая длина * длина;
//Квадрат может быть прямоугольником
//Но это не соответствует отношению поведения, поэтому мы не будем продолжать
//и создаем между ними сильную связь
//Может быть, это фигуры. У нас пока недостаточно примеров и протокола
//Мы не будем гадать, пока не узнаем
Обнаружение
Абстрактный класс только с одним подклассом является индикатором преждевременной классификации.
Теги
- Плохой дизайн
- Классификация
Вывод
При работе с классами мы называем абстракции, как только они появляются.
Наше правило — выбирать [хорошие имена] (https://hackernoon.com/what-exactly-is-a-name-the-quest-part-i-fmw3udc) после поведения.
Мы не должны называть наши абстракции, пока не назовем наши конкретные подклассы.
Связи
[Code Smell 11 — Подклассификация повторного использования кода] (https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iii-t7h3zkv)
Больше информации
- [Что в имени] (https://hackernoon.com/what-exactly-is-a-name-the-quest-part-i-fmw3udc)
Кредиты
Фото [Фэй Корниш] (https://unsplash.com/@fcornish) на [Unsplash] (https://unsplash.com/s/photos/tree)
Давайте изменим наше традиционное отношение к построению программ: вместо того, чтобы воображать, что наша главная задача — инструктировать компьютер, что делать, давайте лучше сосредоточимся на объяснении людям того, что мы хотим, чтобы компьютер делал.
Дональд Э. Кнут
[Великие цитаты о программной инженерии] (https://hackernoon.com/400-thought-provoking-software-engineering-quotes)
И это пока все…
В следующей статье мы расскажем еще о 5 запахах кода!
Оригинал