Bug fixing как часть прикладной психологии.
Порой исправление даже самых очевидных ошибок может буксовать из-за особенностей человеческой психологии. Свежий пример: компонент A передаёт компоненту B набор параметров, в том числе текстовые строки. Строки передаются в виде UNICODE_STRING, т.е. как текстовые строки, не требующие завершающего нулевого символа. Не смотря на это, компонент A передавал строки с завершающим NULL (упакованные в UNICODE_STRING), а компонент B проверял приходящие строки на наличие нуля. Так они и работали, пока между ними не вклинился третий компонент X.
Компонент X выборочно менял строки, идущие от A к B, теряя по пути нулевые символы. Что совершенно законно, раз речь идет про UNICODE_STRING. Результат – компонент B ругается страшными словами и ничего не работает.
Встал вопрос кого править. Казалось бы, ответ очевиден – правим B, поскольку иначе придется менять протокол (тип строк) и править всех. Однако не тут-то было. Команда компонента B предъявила «железный» аргумент: наш код не менялся и замечательно работает уже X лет, а тут пришли вы со своим X и всё поломали. (Я тут утрирую, конечно). Ситуацию усугубило то, что исправить ошибку нужно «здесь и сейчас», а потом будет поздно…
Сложилась довольно странная ситуация. Вроде бы все понимают, что виноват компонент B. И что работал он только по счастливой случайности. Тем не менее, самого факта того, что он работал уже какое-то время достаточно для того, чтобы склонить чашу весов в сторону косметических исправлений, вместо устранения корня проблемы. Даже то, что любое косметическое исправление только прибавляет хлопот в будущем, не было весомее наличия «опыта работы» у компонента B.
Конечно, в конце концов, был починен именно компонент B, однако осадок остался…
Ну, в общем правильно сказали. Если “B” работал X лет, то любое изменение “B” требует большого тестирования его самого и всех с ним связанных компонент, которые использовали его особенность передачи UNICODE строк.
В этом плане дешевле сделать у “X” такой же способ передачи строк, который ожидает “B” от “A”, до следующего запланированного рефакторинга “B” и “A” (с учетом приведения протокола передачи строк в нормальный вид). Второй вариант, если позволяет архитектура - это добавление промежуточного слоя между “X” и “B”, который будет конвертировать строки при вызове из правильного в неправильный, сужая тем самым кривизну в остальных компонентах.
Как по мне - это единственный приемлимый вариант затычки в данном случае. Только предлагалось поправить сам B так, чтобы он создавал для себя копии строк в том формате, какой ему нужен. Людой другой вариант, не затрагивающий B, - суть рассыпание граблей, на иправление которых будет потрачено больше сил, чем исправление интерфейса B.
А чего тут думать? Кто у нас не соответстввет спецификации? B. Следовательно, его и надо расстрелять править. То, что баг в нем жил и здравствовал с 1917 года, не есть оправдание.