środa, listopad 24, 2010

Historia Tomka - przeciążanie

If debugging is the process of removing bugs, then programming must be the process of putting them in. ~Author Unknown
My software never has bugs. It works *exactly* as I wrote it! ~ Author Unknown

Dzisiejsza historia oparta jest, w większości, na faktach. Ukryliśmy tylko imię naszego programisty.

Był sobie Tomek programista. Tomek miał do napisania w C# fragment większego algorytmu. Jako, że kod był dobrze podzielony mogło to zrobić wiele osób. Jedną z rzeczy które miały być w tym fragmencie było stworzenie wektora z dwóch elementów:
[1 Math.Pow(Math.Sqrt(2), -BassCorrectRaw)-1]
Tomek nie był pozostawiony sam sobie. Miał API, które było dość rozbudowane.
Był dostępny typ VectorDouble jak poniżej:

public class VectorDouble : Vector<double>, IVectorDoubleReadOnly

{                       

    public VectorDouble() : base()

    { }

 

    public VectorDouble(int size) : base(size)

    { }

 

    public VectorDouble(int size, double value) : base(size, value) 

    { }

 

    public VectorDouble(params double[] vector) : base(vector)

    { }       

   //...

}

Wystarczyło go użyć i zainicjować wartościami co też nasz bohater uczynił. Napisał taki oto kod:

IVectorDoubleReadOnly BassCorrectCoefA = new VectorDouble(1, Math.Pow(Math.Sqrt(2), -BassCorrectRaw) - 1);

Widzicie już problem Tomcia? Jeśli chcecie pomyśleć sami to nie klikajcie na poniższy link. Jak już się zdecydujecie to zapraszam do dalszego czytania.

Pokaż rozwiązanie

4 komentarze:

Gutek pisze...

API jest winne. jest nie jasne i prowadzi do nieumyślnego spowodowania błędu i to nie jest wina programisty ale Tworcy API, ze umozliwil nieokreslone jej wykorzystanie.

Dodatkowo testy Unit sa zle popisane :)

Piotruś pisze...

A gdybym zamiast 1d napisał 1.0 będzie ok?

noisy pisze...

skoro jak widać klasa bazowa nie musi przyjąć size w konstruktorze, to być może lepiej było by, aby size było ustawiane osobną funkcją. Prawda jest jednak taka, że ciężko jest coś takiego przewidzieć pisząc API - ja przynajmniej mógłbym nie wpaść na to, że jest to błędogenne.


Inna sprawa, że można było rozwiązać przyjmowanie doublów w jakiś jawny sposób, np. za pomocą jawnego vectora czy tablicy, nawet jednoelementowej...

pawlos pisze...

@Piotruś: Tak. Użycie 1.0 załatwiłoby sprawę.

@noisy: Zapewne tak trzeba byłoby to rozwiązać. Co do błędogenności tego rozwiązania niech najlepiej świadczy fakt, że jak szukałem dlaczego to źle liczy to z reguły pomijałem ten fragment zakładając jego poprawność. Jednak błędnie i dopiero jak się przyjrzałem mu dokładniej zobaczyłem w czym leży problem.