Никогда! На этом, в общем можно было бы и закончить, но я все же напишу больше.
Мне довелось однажды оказаться в ситуации, когда мне поручили сдать проект, притом, что отгрузка (он же дедлайн) была очень близка. В проекте участвовало несколько человек: программист прикладной части ПО (он же менеджер проекта) и программист программы контроллера, и программист контроллера в части системы сигнализации и связи с АСУ ТП (моя часть). Проект уже был в стадии, когда самый главный начальник несколько раз в неделю приходил в кабинет и настойчиво спрашивал о сроках завершения проекта. Моя часть была завершена, и я был спокоен. Обещали сдать до нового года, но, увы и ах как-то не выходило. Основная часть программы контроллера была не готова. Результаты тестирования содержали более 20 страниц формата А4 с описанием, в основном, критических багов.
После нового года ко мне подходит менеджер проекта и говорит о том, что программист контроллера уезжает на обучение, а после этого будет переведен на другой проект и поэтому мне придется заняться основной частью программы. Исправить баги и сдать ее как можно быстрее. Мой непосредственный начальник не сказал мне поэтому поводу ни слова. Сейчас я вспоминаю те дни и корю себя за то, что не пошел к нему, и не начал разбираться как же так получилось. Возможно, стоило вообще отказаться от выполнения поставленной задачи, ну или предложить условия, на которых это будет сделано. Но тогда случилось так, что я согласился на то, чего пока еще мало понимал. Тогда я постеснялся выразить свое недовольство и, молча, принялся доделывать и справлять чужую программу. Сейчас я вспоминаю это и в целом даже рад, что так получилось, ведь опыт, как говорится, не пропьешь.
Ситуация осложнялась тем, что я до этого не вникал в физику работы устройства, с которым работала основная программа, я очень туманно знал про структуру ПО и принцип ее работы, а также то, что программист, который ее писал через два дня уезжал на обучение, а после обучения на большинство моих вопросов он отвечал так, что мало чего помнит и вообще был занят другим проектом. И, конечно, самое неприятное это сроки.
Вначале я даже немного запаниковал, были мысли о том, что я могу не справится или выполнить все ужасно, но потом я оценил ситуацию так, что терять мне все равно нечего, потому как куда уже хуже и принялся думать о том, как сделать все так, чтобы тестирование было пройдено, а мне это обошлось малой кровью.
Малой кровью это не обошлось: пришлось задерживаться, пришлось много раз прочитать документы, которые были написаны (хорошо, что они были), пришлось много раз прочитать чужой код и процентов на 80 в нем разобраться, пришлось разбираться с аппаратурой и ее особенностями (тем, кто работал с DC time и модулями Ethercat меня поймет).
Вот с чем мне пришлось иметь дело:
- EtherCAT + DCTIME
- Настройка модулей EL1252, EL3702
- Межзадачное взаимодействие
- Кольцевой архив событий
- Связь с АСУТП (протокол МЭК 104)
- Связь с прикладной программой (Modbus TCP)
- Сигнализация
- Различный функционал (синхронизация времени, вотчдог, чтение и запись параметров и т.д.)
После того, как с горем пополам проект был доделан и прошел тестирование (я иногда удивляюсь как это так получилось) встала необходимость распространить ПО на устройства другого типа. И тут началась жесть... Мало того, что текущий код был плохим (очень хочется написать другое слово), так теперь его предстояло распространить на устройства другого типа. Это было сделано. Теперь программ с плохим кодом стало две, а позже 3. Они работали и все прошли выходное тестирование, но сопровождать это ПО и тем более отвечать на вопросы связанные с потенциальными багами было очень затруднительно.
Порядка 20 устройств уехало с данным ПО в разные места. Я и сам участвовал в наладке и запуске на нескольких объектах. На наладке были выявлены еще ряд моментов, которые требовалось обсудить и, возможно, на их основании внести изменения в ПО. Плюс наклевывался еще один заказчик, который хотел дополнительный выходной дискретный сигнал и дополнительный функционал. Эти изменения касались все трех видов ПО и в тот момент я подумал, что это шанс упускать нельзя. И тут я принялся за разработку новой архитектуры с учетом прошлых недочетов. Требования были простыми:
-
выпустить одну полностью универсальную программу на все три типа устройства;
-
заплатить за универсальность - ресурсами (памятью), которых на тот момент было 50% в резерве;
-
сократить использование энергонезависимой памяти, так как запись в нее очень медленная;
-
устранить многочисленные участки повторяющегося кода заменой на функции, функциональные блоки;
-
добавить функционал, на который не хватало времени ранее.
На текущий момент новое ПО находится в фазе окончательного тестирования. Баги, конечно были найдены, но их идентификация и исправление было намного проще, чем ранее. Полностью универсальное ПО получить не удастся, по крайней мере на текущий момент, но уже есть планы как это можно исправить. Потребление энергонезависимой памяти сокращено в 2 раза. Процентов на 80 повторяющийся код заменен на функции или функциональные блоки. Могу сказать, что теперь я доволен тем, что сделано.
Доволен, но не до конца. После завершения тестирования всех типов устройств вся система уйдет в эксплуатацию, которая покажет кто был прав. Могу сказать, что может случиться все что угодно, однако теперь я менее обеспокоен вопросами анализа и поиска дефектов, которые могут проявиться.
В завершении хотелось бы отметить, что, возможно, я слишком драматизировал и зря переживал насчет старого программного обеспечения. Оно работало и прошло все выходные тесты. И, возможно, даже следовало бы вспомнить правило "Работает - не трогай!", но тут я был твердо уверен в том, что я хочу сделать. Как показал опыт, обслуживать три версии ПО, достаточно трудоемко. Мое мнение было и остается таким, что уж лучше потратить время на переработку и переписывание программы и сделать ее более понятной, менее избыточной в части повторения кода и, главное, в единственном экземпляре, нежели с ужасом вспоминать и разбираться в трех плохих программах при появлении вопросов или претензий от заказчика.
Закрывать глаза на плохой код нельзя, но можно призакрыть глаза на некоторое время, если этот плохой код является рабочим и программа выполняет все выходные тесты. Такую программу можно и нужно отправить заказчику, чтобы не затягивать сроки и она, скорее всего, даже может работать в течении длительного времени, но, при любом удобном случае, следует выделить время и учесть все недочеты, которые были выявлены и эффективно устранить их. Сделать программу понятной, универсальной, более простой это те принципы, которых я старался придерживаться при внесении изменений и думаю, что работу, которая я выполнил еще принесет свои плоды. Я также уверен в том, что практика написания плохого кода, с учетом его дальнейшего исправления - плохая практика, но, иногда, в силу определенных причин, так происходит.
Прошлые записи
- Комната призвания
- Разбираемся с Coroutine в Kotlin - часть четвертая
- Разбираемся с Coroutine в Kotlin - часть третья
- Разбираемся с Coroutine в Kotlin - часть вторая
- Разбираемся с Coroutine в Kotlin - часть первая
- Отпуск длинною в год
- Подходит ли data class для JPA Entity?
- События как источник правды или как я в стартапе участвовал
- Код 2015 против 2023
- Jvm Internals - Перевод
- Мозг против живота или насколько трудно управлять своей жизнью