Czy inni naprawiają błędy, gdy je widzą, czy czekają, aż nastąpi awaria / utrata danych / ludzie umrą, zanim to naprawią?
Przykład 1
Customer customer = null;
...
customer.Save();
Kod jest wyraźnie niepoprawny i nie można go obejść - wywołuje metodę w odwołaniu zerowym. Zdarza się, że nie ulega awarii, ponieważ Save
nie ma dostępu do danych instancji; więc to tak jak wywoływanie funkcji statycznej. Ale każda niewielka zmiana w dowolnym miejscu może nagle spowodować uszkodzenie kodu, który nie ulega awarii: aby rozpocząć awarię.
Ale nie jest również wykluczone, że poprawianie kodu:
Customer customer = null;
...
customer = new Customer();
try
...
customer.Save();
...
finally
customer.Free();
end;
może wprowadzić awarię; jeden nie wykryty przez testy jednostkowe z pełnym pokryciem i ręczne testy użytkownika.
Przykład 2
float speed = 0.5 * ((G * mass1 * mass2) / R) * Pow(time, 2);
Ludzie znający fizykę będzie wiedział, że to ma być R 2 w mianowniku.
Kod jest niepoprawny, jest absolutnie niepoprawny. Przeszacowanie prędkości spowoduje, że rakiety retro wystrzelą zbyt wcześnie, zabijając wszystkich pasażerów statku kosmicznego.
Być może jednak przeszacowanie prędkości może maskować inny problem: poduszki powietrzne nie mogą się wysunąć, gdy prom porusza się zbyt szybko. Jeśli nagle naprawimy kod:
float speed = 0.5 * ((G * mass1 * mass2) / Pow(R, 2)) * Pow(time, 2);
Teraz prędkość jest dokładna i nagle poduszki powietrzne otwierają się, kiedy nie powinny.
Przykład 3
Oto przykład, który miałem ostatnio, sprawdzanie, czy ciąg znaków zawiera nieprawidłowe znaki:
if (StrPos(Address, "PO BOX") >= 0)
{
//Do something
}
Co jeśli okaże się, że w Do something
oddziale jest błąd ? Naprawianie oczywiście nieprawidłowego kodu:
if (StrPos("PO BOX", Address) >= 0)
{
//Do something
}
Naprawia kod, ale wprowadza błąd.
Moim zdaniem są dwie możliwości:
- napraw kod i obwiniaj go za złamanie
- poczekaj, aż kod się zawiesi, i obwiniaj się za błąd
Czego ty politycznie zrobić?
Przykład 4 - dzisiejszy błąd w świecie rzeczywistym
Konstruuję obiekt, ale wywołuję niewłaściwy konstruktor:
Customer customer = new Customer();
Okazuje się, że konstruktor „bez parametrów” jest tak naprawdę sparametryzowanym konstruktorem z dalszej części łańcucha dziedziczenia:
public Customer(SomeObjectThatNobodyShouldBeUsingDirectly thingy = null)
public Customer(InjectedDependancy depends)
Wywołanie go jest błędem, ponieważ pomija wszystkie kolejne konstruktory.
Mógłbym zmienić rodowód obiektu, aby nie ujawniać tak niebezpiecznego konstruktora, ale teraz muszę zmienić kod na:
Customer customer = new Customer(depends);
Ale nie mogę zagwarantować, że ta zmiana niczego nie zepsuje. Podobnie jak w powyższym przykładzie 1 , być może ktoś gdzieś, w jakiś ezoterycznych warunkach, zależy od tego, że jest skonstruowany Customer
jako nieważny i pełen śmieci.
Być może Customer
obiekt, teraz, gdy jest poprawnie skonstruowany, pozwoli na uruchomienie kodu, który nigdy wcześniej nie działał, a teraz mogę dostać awarię.
Nie mogę się w to założyć o życie twojej żony.
I mogę to przetestować od tutaj do wtorku, nie mogę przysiąc na życie twojej córki, że nie wprowadziłem regresji.
Czy ja:
- Napraw kod i obwiniaj go za złamanie? lub
- Zostaw błąd i poczuj się winny, gdy klient go znajdzie?