Code contracts

Requires

kajdany

W teorii są 3 rodzaje kontraktów. Podejdę wg mnie praktycznie i opowiem głównie o pierwszym (Requires), z pozostałych dwóch rzadko kto korzysta. Requires używa się do sprawdzania argumentów przekazanych do metody.

Kod bez kontraktów:

public static void Foo(string argument)
{
    if (argument == null)
        throw new ArgumentNullException("magic string about argument name");
}

Kod z kontraktami:

public static void Foo(string argument)
{
    Contract.Requires<ArgumentNullException>(argument != null);
}

Z kontraktami prościej jest sprawdzić całą tablicę:

    public static void Bar(IEnumerable<Employee> employees)
    {
        Contract.Requires<ArgumentException>(Contract.ForAll(employees, p => p != null));
    }

Działanie

Do działania Code Contracts niezbędne jest pobranie instalki. Trzeba ja też zainstalować na Build Serverze. Kontrakty nie są dodawane podczas zwykłej kompilacji, tylko do już skompilowanych bibliotek. Do kodu Common Intermediate Language skompilowanej biblioteki dodawany jest kod CIL który odpowiada za sprawdzenie kontraktów.

Czy tylko w debugu?

Nie jest to narzędzie czysto debuggerskie (jak sądzą niektórzy) tylko jak najbardziej dla kodu produkcyjnego. Można je włączyć lub wyłączyć w opcjach projektu, jest osobna zakładka. Ja korzystam w nich w runtime na produkcji, bo lepiej zobczyć wyjątek przy wejściu do metody niż puszczać i zobaczyć NullReferenceException. Lepiej domyślenie włączyć, mieć feedback z logów (poprawić bugi), a gdy ktoś się poskarży na performance to wtedy wyłączyć.

Wiele tutaj zależy od tego jak często z nich korzystamy. Ja staram się je umieszczać głównie na granicach, gdzie mój kod jest wywoływany przez zewnętrzny kod. Kod pod moją (teamu) kontrolą jest pod nasza kontrolą i tutaj sami musimy dbać o jakość. Takim przykładem jest zwracanie pustych kolekcji zamiast nulli, oraz korzystanie z Null Object Pattern.

Pozostałe kontrakty

Przez kilka dni nie znalazłem nikogo, kto z nich korzysta (może oprócz Ensures, ale tak na siłę). Warunki, które sprawdza Ensures (stan po zakończeniu działania funkcji) lepiej sprawdzić za pomocą Unit Testów, czyli z zewnętrznie testowanej metody/klasy. A może to tylko moje przyzwyczajenie?

Zauważyłem kiedyś u znajomego, że on nie uznaje Unit Testów bo woli właśnie kontrakty. Nie byłbym taki ortodoksyjny, wole pisać testy a kontrakty używać jak już wspomniałem głównie do walidacji argumentów wejściowych.

Jest też statyczna analiza kodu (to jest naprawdę super), ale to już innym razem.

Reklamy
Ten wpis został opublikowany w kategorii Programowanie i oznaczony tagami , , , . Dodaj zakładkę do bezpośredniego odnośnika.

Jedna odpowiedź na „Code contracts

  1. Pingback: dotnetomaniak.pl

Możliwość komentowania jest wyłączona.