По просьбе хаброжителей публикуем еще одну короткую главу и оглавление из книги СергеяТарасова «Дефрагментация
Code revision или коза кричала
Ревизия программного кода всякий раз напоминает мне эпизод из фильма Г. Данелия «Осенний марафон». Главный герой, преподаватель университета Андрей Бузыкин сидит у своей бывшей сокурсницы Варвары, помогая ей с переводом художественного произведения. Время перевалило за полночь, происходит примерно такой диалог.
– Скажи, Бузыкин, может я бездарная?
– Не-е-е…
– Но ты же всё повычеркивал!
– Не всё… Но вот это, например, я не мог оставить: «Коза кричала нечеловеческим голосом»
Мой коллега, обладатель диплома историка, переквалифицировавшийся в консультанты по BI, как-то посетовал, что он плохой программист. Будучи несколько удивлённым, я успокоил его тем, что в BI программирования как такового немного, и критичные куски кода всегда могут помочь написать коллеги соответствующей специализации, стоит обратиться к ним по внутренней рассылке. Хуже, когда вполне программистский коллектив умудряется годами работать без системы контроля версий исходников, и тогда в коде половину объёма составляют закомментированные куски многолетней давности. Выбросить их жалко, вдруг пригодятся. Но и контроль версий с архивацией не спасают от цифровой пыли десятилетий. В подобных залежах порой можно обнаружить настоящие образцы софтостроительных анти-практик.
Например, одна ERP-система много лет назад переносилась из файл-серверной архитектуры в среду клиент-серверной СУБД. Вполне ожидаемо в базе данных обнаруживается таблица типа «мегасправочник», хранящая все ссылки вида «ключ-значение». Структура состоит из трех колонок: код справочника, код значения и само значение. В прежней архитектуре ссылочная целостность поддерживалась приложением, теперь же стандартным образом приспособить для этой цели транзакционную СУБД невозможно, потребуется написать достаточно длинный линейный триггер.
Такой универсализм стал причиной использования магасправочника одновременно для хранения внутренних счётчиков нумерации записей: текущая величина хранилась в строковом поле колонки «Значение» в формате «префикс; текущий номер». Приложение считывает текущее значение счётчика, анализирует строку, выделяя префикс и величину, переводит величину из строки в целое, увеличивает его на 1, формирует новое значение строки и снова записывает всё это обратно в базу данных.
Кроме перечисленных манипуляций со строкой, вначале делается попытка заблокировать запись через соответствующую опцию SQL-запроса. Мысль правильная, но, к сожалению, блокировка делается вне контекста транзакции, то есть снимается сразу после окончания выполнения запроса. На вопрос: «У вас конфликтов нарушения первичного ключа не было?» был дан самый оригинальный ответ за всю мою практику: «Они нам мешали делать каскадные обновления в связанных таблицах и мы их удалили, оставив просто индексы».
В другом случае на форме Delphi-приложения имелась группа из двух опций (радиокнопок) для взаимоисключающего выбора. Кнопки были подписаны как «Объём ограничен» и «Объём неограничен». Вроде бы ничего особенного. Но открываем форму и обнаруживаем что кнопка с надписью «Объём ограничен» поименована программистом как «КнопкаОбНеограничен». И, разумеется, наоборот. Ошибся человек, бывает…
К счастью, в коде формы есть только одно место, где значения кнопок используются. Видимо, во избежание путаницы процедура оформлена следующим образом:
var ОбъёмТакиОграничен: boolean;
...
if КнопкаОбНеограничен.Выбрана then
ОбъёмТакиОграничен := true
else
ОбъёмТакиОграничен := false;
...
ВызовКакойТоФункции(ОбъёмТакиОграничен);
Дальше ревизия коснулась SQL-кода. Программист пытался выбрать следующий элемент списка, обрабатывая только первую запись из пришедшего по запросу набора. При этом сортировку он делал совсем по другой колонке, нежели порядковый номер в списке. В итоге выбиралось что угодно, но не следующий элемент.
Не буду утомлять вас другими примерами, надеюсь, вы просто поверите в их многочисленность и оригинальность. Мне хотелось лишь донести простую мысль, что ревизия кода, несомненно, весьма полезная процедура, но, как минимум, при двух условиях:
• эта процедура регулярная и запускается она с момента написания самых первых тысяч строк
• процедуру проводят специалисты, имеющие представление о системе в целом. Потому что отловить бесполезную цепочку условных переходов может и компилятор, а вот как отсутствие контекста транзакции в обработке повлияет на результат определит только опытный программист
Дж. Фокс [2] выводит из своего опыта проектной работы в IBM важную мысль, что большой ошибкой является привлечение к процессу внутреннего тестирования и обеспечения качества посредственных программистов. По его мнению, компетентность специалиста в этом процессе должна быть не ниже архитектора соответствующей подсистемы. Действительно, ведь оба работают примерно на одном уровне, просто один занят анализом, а другой – синтезом.
Качество кода во многом зависит от степени повторного использования, поэтому приведу простой и доступный способ проверки, не занимается ли ваша команда программистов копированием готовых кусков вместо их факторизации. Для этого регулярно делайте сжатый архив исходников, например zip с обычным коэффициентом компрессии, и оценивайте динамику роста его размера относительно числа строк. Если архив растёт медленнее, чем строки, это означает количественный рост размера кода за счёт его копирования.
Оглавление
О нашей профессии
Очень краткий экскурс
Специализация
Кто такой ведущий инженер или как это было
Метаморфозы
О красоте
6 миллионов на раздел пирога
Профориентация
Начинающим соискателям
Про CV
Про мотивацию
Изгибы судьбы при поиске работы.
Технологии
Конструировать ли программы как аппаратуру?
Безысходное программирование
Эволюция аппаратуры и скорость разработки
Диалог о производительности
О карманных монстрах
ASP.NET и браузеры
Апплеты, Flash и Silverlight
ООП – неизменно стабильный результат
ORM или объектно-реляционный проектор
ВЦКП в облаках
От CORBA к SOA
Прогресс неотвратим
Проектирование и процессы
Краткий словарь для начинающего проектировщика
Слоистость и уровни
Многозвенная архитектура
История нескольких #ifdef
Ultima-S – КИС из коробки
Нешаблонное
Думать головой
Журнал хозяйственных операций
UML и птолемеевские системы
Когда старая школа молода
«Оптисток» или распределённый анализ данных
Архитектура сокрытия проблем
Code revision или коза кричала
Наживулька или гибкость?
Приключения с TFS
Программная фабрика: дайте мне модель, и я сдвину Землю
Лампа, полная джиннов
Остановиться и оглянуться
Cherchez le bug или программирование по-французски
О технических книгах
Дефрагментация
Простые правила чтения специальной литературы
Литература и программное обеспечение.
Вместо послесловия или краткое изложение «Оснований»
Литература
Автор: ph_piter