Я расскажу вам три моих простых приема.

Я никогда не считал себя хорошим программистом. Если бы я был хорошим, то написал бы эти строки из офиса Яндекса или других крупных ИТ-компаний, возможно, даже зарубежных. Но я пишу эти строки из среднего «ООО», которое работает белым цветом.

Однако, когда я смотрю на код своих коллег и общаюсь с некоторыми тестировщиками, волосы иногда шевелятся во всех местах, и я начинаю казаться гением в собственных глазах, хотя бы потому, что использую основы ООП или самые основные приемы повторного использования кода.

Общение с тестировщиками пока пропущу, так как это тема для отдельных постов. Думая о плохом коде. Многое можно назвать плохим кодом. Это зависит от уровня проекта, уровня компании и уровня программистов.

В конце концов, если компания из 50 человек хочет, чтобы велосипед управлял каким-то бизнес-процессом, то идеальный код ничего не изменит. Так что пусть это останется мусором, но если есть желание посоревноваться за качество моей работы, могу предложить методики, которые использую в своей работе сам.

  • Да, эти методы очевидны.
  • Да все о них знают.
  • Да ничего нового не скажу.

Но мой личный опыт показывает, что многие программисты работают по принципу «сделал и ладно». Что ж, поделюсь личным опытом.

Первый используемый метод – модульные тесты. Это самое сложное, нудное и долгое, и кстати, если в процессе написания тестов — невыносимо. Так что код проекта - мусор. Какие проблемы?

  • Цикломатическая сложность — при использовании в методе каждый новый тест дает +1 к 100% охвату. Если вы написали юнит-тест для белого скрипта метода, покрывающего только 10–20% кода метода, то ваш код — мусор.
  • Длина метода — Набили шишки по сложности и написали простой метод в 150 строк. Начали писать юнит-тест, и на 10-й настройке мока глаз начал дергаться, а кнопки CTRL+CV стали глючить. Несмотря на внешнюю простоту, ваш код зависит от результатов работы многих других модулей. Соответственно любой из них может кинуть исключение. Так что ваш код - мусор.
  • Использование «окружения» — это снова тема с моками. Нравится нам это или нет, но мы используем некоторые глобальные системные сущности. Например — конфигурация, сеанс и пользовательская сущность, в контексте которой выполняется метод. Если вы не можете быстро и легко смоделировать эти объекты, то ваш код ужасен. Это сильно зависит от внешней среды, которую вы мало контролируете.

Что в итоге — нужно писать тесты не только для тестирования. К сожалению, они все еще мало помогают в выявлении плохого кода.

Второй используемый метод – использование готовых решений. Опять же, в качестве примера я использую сборку AutoMapper. Для тех, кто не в курсе, эта библиотека одним вызовом метода Map позволяет спроецировать объект одного класса в объект другого.

Я не знаю более простой задачи — что сложного в том, чтобы вызвать конструктор и передать ему все необходимые параметры? И все же есть трудность.

Во-первых, если изменится структура сущности, вы просканируете весь код и внесете изменения. Могу ли я написать свой преобразователь? Да, ты можешь. Сколько у вас объектов и сколько конверсий вам нужно? Можете ли вы написать завод? Да, ты можешь. Только проблема та же.

Классов скорее всего много, и как они будут расти — вы не знаете, а если добавить к этому нежелание писать тесты на производимую ерунду, то шанс глючить проблемы вырастает в геометрической прогрессии. Но можно использовать готовые.

Вам нужно написать конфигурацию сопоставления и вызвать один единственный метод одного интерфейса. Хотя стоит признать, что конфигурацию тоже лучше покрыть тестами.

Иногда 30 минут поиска готового решения заменяют недели работы и годы поддержки ваших решений. Хотя стоит признать, что конфигурацию тоже лучше покрыть тестами.

Я продолжаю сталкиваться с чудовищными вызовами конструктора. Если произойдет ошибка, вы никогда не найдете, где она возникла. Но есть простая альтернатива. И это касается почти любого действия. Да, у каждого проекта есть своя бизнес-логика, но можно реализовывать сериализацию/десериализацию XML, управление потоком, взаимодействие с базой данных и т.д. и т.п.

Последний, но не менее важный трюк, о котором я хочу упомянуть, — это пара вопросов, которые вы должны задать себе после (а лучше ДО) написания кода.

1. Кто будет использовать этот код?

Вопрос очень общий, но я приведу пример. Предположим, вы прописали некоторую логику в коде контроллера. Через полгода мы узнали, что руководство хочет сделать мобильное приложение, которое делает то же самое. И теперь перед нами стоит задача перенести код на уровень бизнес-логики. Ну или скопировать-вставить в логическую прослойку мобильного приложения. И то, и другое плохо, и все из-за нежелания понимать, что такое «Логика бизнеса», что такое «уровень доступа к данным» и что такое «взаимодействие с внешними сервисами».

2. Как этот код будет развиваться в будущем?

Если вы ответите «ни за что, это для одной текущей задачи» — я вас расстрою. Вы написали фигню. Рано или поздно возникнет потребность в повторном использовании. Конечно, можно надеяться, что ваш потомок перепишет ваш код, который будет более универсальным, но лучше сделать это самому, чем потом рисковать копипастом коллеги.

Мой личный обнаруженный рекорд — 20 методов копирования-вставки в контроллере — 10 приложений от клиента, два способа доставки результата. И авторам наплевать на этот факт. Это никому не режет глаза.

Ну а теперь к результатам.

Результата как всегда нет. Плохой код был, есть и будет. У вас никогда не будет времени на рефакторинг.

Вы хотите что-то изменить? Для начала не усугубляйте ситуацию и хотя бы своим примером покажите, как вы можете это сделать. Да, я знаю, мой совет очевиден. Но я вижу много людей, которые могут и знают все эти мысли, но почему-то не воплощают их в жизнь.

Я буду безмерно рад, если мои слова помогут хотя бы одному человеку писать код лучше.

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .

Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.