вторник, 10 ноября 2009 г.

[comp.prog.thoughts] Маленький прием, позволяющий идентифицировать reusabe-кода

По мотивам обсуждения заметки Code reuse в блоге Алёна C++.

Повторное использование кода – это сложный вопрос. Он сложен даже для маленьких команд. Еще сложнее он в больших командах и больших организациях с развитой бюрократией. Но здесь у меня мало опыта. Поэтому я расскажу всего об одном простом приеме, который позволяет выявить повторно используемый код.

На мой взгляд, повторно используемый код бывает двух типов. Первый тип – это код, для которого с самого начала понятно, что он может использоваться в нескольких местах. Как правило, это библиотеки, решающие какие-то четко определенные задачи: алгоритмы сортировки, генераторы случайных чисел, регулярные выражения, средства работы с БД и даже большие фреймворки вроде MFC, Qt или wxWidgets. С этим типом кода все понятно.

Второй тип – это код, о котором изначально не думали как о повторно используемом. Но который затем распространяется между проектами посредством copy-and-paste и, тем самым, приводит к дублированию.

Такой код пишется для решения какой-то конкретной прикладной задачи. Например, в модуле приема данных по сети возникает необходимость залогировать фрагмент сбойного пакета. Для чего разработчик пишет несколько вспомогательных процедур, возможно, завязывая их на конкретный тип логгера.

Если потом в другом модуле потребуется выполнить аналогичное логирование, то другой разработчик может взять процедуры логирования, написанные первым разработчиком. В лучшем случае они заработают без изменений (все-таки в рамках одного коллектива вряд ли будут использоваться разные логгеры), в худшем – потребуют небольшой доработки напильником.

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

Итак, фрагмент чужого кода взят к себе. Потенциально, он может потребоваться еще раз, но об этом пока не известно. Имеет смысл специальным образом пометить этот фрагмент. Ведь когда он потребуется еще раз, то разработчик будут знать, что код уже был скопирован ранее. Я помечаю такой код комментарием:

//FIXME: данный код взят из проекта XYZ.
...

И, когда мне приходится копировать его еще в одно место, данный комментарий напоминает мне, что однажды я уже поленился или не смог выделить его в повторно используемый компонент. Значит, если сейчас для этого есть шанс, я должен этот шанс реализовать.

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

Примечание 2. Наверное, кроме метки FIXME, стоило бы снабжать такой код еще какой-то легко запоминающейся меткой. Например, REUSE. Но у меня эта практика не прижилась, т.к. есть привычка помечать код, подлежащий дальнейшей доработке маркером FIXME (он, кстати, выделяется в ViM-е другим цветом), а дополнительные маркеры я забываю ставить.

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

Примечание 4. Для того, чтобы найти исходный фрагмент кода для copy-and-paste, нужно знать, что он есть :) В собственных проектах с этим еще как-то можно разобраться. А вот с чужими как быть? Временами спасает процедура code review. После того, как выполнишь рецензию чужого кода в голове останутся воспоминания о его содержимом. В нужный момент они могут сработать.

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