Другие люди исправляют ошибки, когда видят их, или они ждут, пока не произойдет сбой / потеря данных / люди не умрут, прежде чем их исправлять?
Пример 1
Customer customer = null;
...
customer.Save();
Код явно ошибочен, и его нельзя обойти - он вызывает метод с нулевой ссылкой. Это не происходит сбой, потому Save
что не имеет доступа к данным любого экземпляра; так что это как вызов статической функции. Но любое небольшое изменение в любом месте может внезапно привести к сбою кода, который не падает: начать сбой.
Но также немыслимо исправление кода:
Customer customer = null;
...
customer = new Customer();
try
...
customer.Save();
...
finally
customer.Free();
end;
может ввести аварии; один не обнаружен в модульных тестах с полным охватом и ручным тестированием пользователя.
Пример 2
float speed = 0.5 * ((G * mass1 * mass2) / R) * Pow(time, 2);
Люди, знающие физику, поймут, что в знаменателе должен быть R 2 .
Код неправильный, он абсолютно неправильный. А переоценка скорости приведет к тому, что ретро-ракеты начнут стрелять слишком рано, убив всех обитателей космического корабля.
Но возможно также, что из-за переоценки скорости скрывается еще одна проблема: подушки безопасности не могут развернуться, пока челнок движется слишком быстро. Если мы вдруг исправим код:
float speed = 0.5 * ((G * mass1 * mass2) / Pow(R, 2)) * Pow(time, 2);
Теперь скорость точна, и внезапно подушки безопасности разворачиваются, когда не должны.
Пример 3
Вот пример, который я недавно имел, проверяя, содержит ли строка недопустимые символы:
if (StrPos(Address, "PO BOX") >= 0)
{
//Do something
}
Что если окажется, что в Do something
ветке есть ошибка ? Исправление заведомо неверного кода:
if (StrPos("PO BOX", Address) >= 0)
{
//Do something
}
Исправляет код, но вносит ошибку.
На мой взгляд, есть две возможности:
- исправить код и обвинить в его нарушении
- дождаться сбоя кода и обвинить в ошибке
Что ты политически делаешь?
Пример 4 - Сегодняшняя ошибка в реальном мире
Я создаю объект, но вызываю неправильный конструктор:
Customer customer = new Customer();
Оказывается, что конструктор «без параметров» на самом деле является параметризованным конструктором из глубины цепочки наследования:
public Customer(SomeObjectThatNobodyShouldBeUsingDirectly thingy = null)
public Customer(InjectedDependancy depends)
Называть его ошибкой, поскольку он обходит все последующие конструкторы.
Я мог бы изменить происхождение объекта, чтобы не показывать такой опасный конструктор, но теперь я должен изменить код на:
Customer customer = new Customer(depends);
Но я не могу гарантировать, что это изменение ничего не сломит. Как и в моем примере 1 выше, возможно, кто-то где-то, каким-то образом, в каких-то эзотерических условиях, зависит от того, что построенное Customer
является недействительным и полным мусора.
Возможно, Customer
объект, теперь, когда он правильно сконструирован, позволит запускать некоторый код, который раньше никогда не выполнялся, и теперь я могу получить сбой.
Я не могу поставить на это жизнь твоей жены.
И я могу проверить это отсюда до вторника, я не могу поклясться в жизни твоей дочери, что я не ввел регресс.
Должен ли я:
- Исправить код и получить вину за его нарушение? или
- Оставить ошибку и получить вину, когда клиент ее обнаружит?