Как найти вонючие части вашего кода [Часть XIX]

Как найти вонючие части вашего кода [Часть 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: используйте утверждения с декларативными описаниями.


Проблемы


  • Читабельность

  • Жесткая отладка

  • Пустая трата времени

Решения


  1. Поместите красивое описательное утверждение

  1. Делитесь руководствами по решению проблем

Образец кода


Неправильный


```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: не используйте аббревиатуры в подклассах


Проблемы


  • Читабельность

  • Ошибки

Решения


  1. Переименуйте свои классы, чтобы обеспечить контекст

  1. Используйте модули, пространства имен или полные имена

Образец кода


Неправильный


```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)

  • Плохая сплоченность

Решения


  1. Возьмите только один «вид» входных данных

  1. Аргументы должны придерживаться единого протокола.

Образец кода


Неправильный


```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: не импортируйте слишком много.


Проблемы


  • Связь

  • Нарушение принципа единой ответственности

  • Низкая сплоченность

Решения


  1. Прервать урок

  1. Скрыть промежуточную случайную реализацию

Образец кода


Неправильный


```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: Не гадайте, что принесет вам будущее.


Контекст


Аристотелевская классификация - большая проблема в информатике.


Мы склонны классифицировать и называть вещи прежде чем собрать достаточно знаний и контекста.


Проблемы


  • Футурология

  • Плохой дизайн

Решения


  1. Дождаться конкрементов

  1. Рефакторинг поздно

Образец кода


Неправильный


```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 запахах кода!



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE