Каков Ваш код на... запах?
Как люди мы имеем огромное количество различных желез на теле. Как у программистов у нас есть множество строчек кода в проектах. Как у людей некоторые наши железы выделяют запах - хороший или не очень. Как у программистов некоторые наши строчки кода также могут иметь своеобразный "запашок". В мире программирования "запашок" недопустим.
Подобно тому, как неприятный запах может свидетельствовать о различных медицинских проблемах организма, плохо организованный код также может быть симптомом плохо построенной архитектуры приложения. Итак, должны ли мы беспокоиться при наличии "запаха" у нашего кода?
"Запах" кода - это не то же самое, что и баг. Если коротко, "запах" кода - это та ситуация, когда вроде бы нам не очень нравится код, который мы написали, но не так, чтобы его исправлять или переписывать... Это как раз таки фатальная ошибка.
Рост кода подобен по своей природе росту дерева. Отсекание некошерных веток важно, чтобы дерево оставалось в добром здравии. Если этого не делать, ветки становятся все длиннее и длиннее - и, как следствие, процесс сбора плодов также становится затруднительным. Без рефакторинга поддержка кода может стать затратным вложением.
Дурной запах кода усложняет поддержку, так как любой код требует поддержки. Вообще, "запах" кода был классифицирован в зависимости от сценария, который он представляет.
Эта статья - краткий взгляд на различные виды несовершенств кода, чтобы мы могли понять, на что стоит обратить внимание в разрабатываемых продуктах. И давайте быть честными по отношению хотя бы к самим себе: если не сейчас, то никогда.
Что же, начнем!
"Дух" плохих методов
Первое, на что стоит обратить свое пристальное внимание, - это название метода. Также не стоит забывать и о названиях и общей длине параметров. Вот типичный "идеальный" метод:
- Название четкое и ясное
- Не длиннее 30 строчек и принимает не более 5 параметров
- Реализация - простейшая из возможных, нет "мертвого" кода
Здесь представлен список возможных несовершенств:
Название | Описание | |
1 | Мертвый код | метод не используется. |
2 | Ленивый объект | метод делает очень мало работы. |
3 | Посредник | все, что делает этот метод, - это вызывает другой метод. |
4 | Божественный метод | метод исполняет слишком много обязанностей. |
5 | Длинный список параметров | не забываем про рекомендацию в 5 параметров. |
6 | Перекрученная сложность | слишком сложная реализация простых операций. |
7 | Цикличный ад | злоупотребление циклами и условными конструкциями. |
8 | Излишняя близость | метод очень сильно зависит от особенностей реализации другого метода. |
9 | Завистливый объект | метод полагается на данные другого объекта больше, чем на свои. |
10 | Черная овечка | метод сильно отличается от других методов класса. |
"Запашок" класса
Проверяйте название класса и то, насколько реализуемый классом контракт отвечает его сути. Как правило, идеальный класс прекрасно отображает назначение различных сущностей на уровне бизнес-логики и реализует ее в рамках архитектуры, выбранной для самой бизнес-логики.
Вот список возможных несовершенств, связанных с классом:
Название | Описание | |
1 | Ленивый объект | класс выполняет слишком мало работы. |
2 | Посредник | класс ничего не делает, просто вызывает объекты другого класса. |
3 | Божественный объект | класс слишком много о себе возомнил. Реализует слишком много операций. |
4 | Узколобое мышление | слишком примитивная реализация типов с особым назначением. |
5 | Шпион на допросе | реализуемый классом интерфейс не сообщает достаточное количество информации, чтобы понять назначение объекта. |
6 | Эксгибиционист | необязательное раскрытие внутренних деталей реализации. |
7 | Излишняя близость | класс слишком сильно зависит от реализации объектов, на которые он ссылается. |
8 | Жадинка | класс наследует поведения объекта, тогда как на самом деле классу нужны лишь некоторые его фрагменты. |
9 | Неопределенность | разработка класса становится слишком сложной из-за вороха фич, которые "когда-то" будут доведены до ума. |
10 | Непостоянство | класс содержит член данных, не характерный для всего времени жизни объекта. |
Общее впечатление о коде
Рассматривая более высокий уровень абстракции, стоит также упомянуть несколько немаловажных аспектов:
Название | Описание | |
1 | Утраченный смысл | код не совсем точно реализует требуемую от него задачу. |
2 | Выбирай, что хочешь | та же самая проблема уже решена - причем несколькими способами. |
3 | Комбинаторный взрыв | различные участки кода делают одно и то же, но с разным набором параметров. |
4 | Не копируй себя | много идентичного кода. |
5 | Сложность | слишком сложная реализация простых вещей. |
6 | Размазня | нет единого глобального класса. Ответственность размазана по целому вороху промежуточных классов. |
7 | Подводный айсберг | изменения внешне не связанных компонентов затрагивают слишком много вещей. |
8 | Спагетти-код | изменение одного компонента требует множество мелких изменений в других местах. |
9 | Пиар-комментарии | классные комментарии в плохом коде. |
10 | Информационный комок | группа переменных почти всегда передается вместе. |
Стоит также уделить минутку своего внимания комментариям в коде. В то время, как комментирование назначения метода будет полезным для всех, кто читает его, комментирование реализации метода - достаточно спорное решение. Риск состоит в том, что по неосторожности можно использовать упомянутые "пиар-комментарии" к тем строчкам, которые этого отнюдь не заслуживают.
Отличный код таков, что нуждается в малом количестве комментариев, так как его реализация становится понятной интуитивно. Комментарии стоит использовать, когда мы комментируем особенности технических решений, вещи, оставленные для рассуждения или будущие этапы разработки.
Как бы это странно ни прозвучало, но комментарии никогда не должны рассматриваться в качестве обязательных для написания. Также не стоит забывать о различных тестах (в особенности о тех, которые не пишутся просто для повышения процента покрытия кода).
Стереотипы
Конечно же, куда без них. Кто-то может утверждать, что подобные тонкости коддинга начали выделять с прогрессом информационной индустрии. Мол, "запашок" кода очень часто является следствием "плохих привычек" написания или же в силу определенных обстоятельств. Подобные оправдания звучат несколько неубедительно и говорят о тараканах в голове разработчика: каждый уважающий себя программист должен стараться писать хороший код абсолютно всегда. По умолчанию!
Другой стереотип, о котором также стоило бы упомянуть, - это избыточная вера в рефакторинг. Что же, рефакторинг как процедура переписывания кода также может быть выполнен из рук вон плохо. Излишняя цикличность, слишком сложные решения и прочее-прочее запросто может быть добавлено в проект из лучших побуждений - особенно в том случае, если по принципу организации исходный код не сильно отличается от здорового клубка спагетти.
В итоге все разработчики могут "запачкать" свой код. Что хуже, часто это бывает под давлением внешних обстоятельств, особенно у "временных" разработчиков для хотфиксов. Проверки качества кода должны происходить всегда сразу после быстрых релизов.
И в заключение
Большинство из тех проблем, с которыми мы сталкиваемся, часто связаны с логическим промежутком, пропастью между уровнем абстракции выбранного языка программирования и языком бизнеса. Чем больше нам удается отстранится от "самовыражения" посредством языка программирования к бизнес-целесообразности, тем более читабельным и поддерживаемым будет наш код.
Гранулярность, модульность, разделение задач и все те прекрасные теоретические концепции, о которых мы могли слышать до этого, становятся конкретными и вещественными, когда мы загораемся желанием следовать концепции делового прагматизма и утилитарности.
Переводчик: Евгений Лукашук
Статьи по схожей тематике