Когда дублирование кода допустимо

Когда дублирование кода допустимо

Ни для кого не секрет, что дублирование кода — это зло. Понимание принципа DRY (Don’t repeat yourself) указывают как требование в вакансиях разработчиков. Даже можно встретить такое выражение, что если задаётся вопрос по программированию из серии «Зачем это нужно?», смело можно отвечать «Чтобы избежать дублирования»)) С высокой вероятностью ответ окажется верным.

И действительно, наследование, полиморфизм, паттерны проектирования и многие другие вещи были придуманы именно для того, чтобы бороться с дублированием кода. Но что же в нём такого плохого?

Традиционно называют 2 проблемы.

  1. Кода становится элементарно больше. А значит, ухудшается структура и его сложнее воспринимать. Да и вообще всем же известно, что чем меньше кода, тем лучше.
  2. Очень сложно вносить изменения, не наплодив при этом кучу багов. Ведь трудно через полгода вспомнить все места, куда копипастился код. Особенно, если эти изменения были не в одном коммите. Получается классическая ситуация — изменения внесли не везде, какой-то участок пропустили. Здравствуйте, баги!

С дублированием принято бороться переиспользованием участков кода и созданием абстракций. И в теории это работает прекрасно. Но между теорией и практикой лежит огромная пропасть. Так ли всё обстоит в реальном мире?

Прежде всего, создание абстракции требует некоторого опыта и навыков, чтобы код был читаемым и понятным для других разработчиков. Нужно знать определённые паттерны, понимать, какие участки лучше обобщать и т.д. Для обычного джуна это может быть сложновато.

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

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

Код становится менее явным

Так что же тогда делать? Получается, что копипастить плохо. Строить абстракции — иногда тоже такой себе вариант. Как поступать?

Прежде всего, признать, что мы все живём и работаем не в волшебном мире пони и единорогов. То, что ни в коем случае нельзя делать в теории, на практике иногда просто необходимо. А также, что бездумное следование какому-либо подходу до добра не доводит.

Так в каких же случаях допустимо дублировать код?

  1. В тестах. Тесты должны быть максимально простыми и понятными для восприятия. Использование обобщений и абстракций может сделать их менее явными и усложнить. Также в тестах не так критична самая главная опасность дублирования. Если вдруг разработчик забудет изменить какой-то участок скопипасченного кода, к серьёзным багам это вряд ли приведёт.
  2. С тестами разобрались. Но в каких случаях можно дублировать код там, где идёт работа с бизнес-логикой приложения. Для начала нужно оценить примерный срок жизни проекта. Если небольшой краткосрочный проект, то можно спокойно дублировать. Никаких ужасных последствий от этого не будет. Или, например, необходимо в максимально короткие сроки сделать прототип, чтобы показать заказчику или протестировать отклик пользователей. Тут главное скорость, а не качество кода. Поэтому можно обойтись и копипастой, ведь дальше прототипа продукт может и не пойти. В таком случае всем будет вообще без разницы, какие паттерны проектирования использовались при разработке.

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

Создание и поддержание абстракций требует временных затрат. Дублированный код также требует затрат, и чем больше копипаст, тем больше эти затраты. В итоге разработчику необходимо выбрать, что обойдётся дешевле: работать с абстракциями или с дубликатами. И на основе этого принимать решение.

Создание и поддержание абстракций требует временных затрат.

В целом, особенно для начинающих разработчиков подойдёт следующий подход. По началу просто писать код и не обращать внимания на копипасты. Когда их станет три и больше, стоит задуматься, можно ли как-то избавиться от дублирования? Переиспользовать общие участки, например, сделать абстракцию и т.п. Если нужно будет потом вносить изменения, не будет ли проблем с этой абстракцией? Останется ли код понятным для других? И в зависимости от ответов на эти вопросы, выбирать дальнейший путь.

Подводя итоги, можно сделать следующие выводы:

  1. Нет никаких жёстких правил, которым обязательно нужно следовать. В любой ситуации стоит выбирать то, что будет рациональнее
  2. Не нужно плодить дублирующийся говнокод, объясняя это тем, что «так будет понятнее». К дублированию стоит прибегать тогда, когда поддержка такого кода будет дешевле, чем работа с абстракциями.
  3. На практике дублирование не всегда плохо, а обобщения, паттерны и метапрограммирование не всегда хорошо.

Артемий Баумгартен

Автор статьи — Артемий БаумгартенFull Stack разработчик. Артём занимается разработкой приложений для бизнеса при помощи Ruby On Rails и React/Vue. Главная цель в работе — сделать продукт, который будет эфективно решать необходимые бизнес-задачи.

 

[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх