Programowanie kontraktowe

Programowanie kontraktowe (ang. Design by contract, DbC) – w programowaniu, metoda organizowania kodu źródłowego programu w taki sposób, aby wynikało z niego nie tylko jak program ma działać, ale też w jaki sposób zweryfikować poprawność działania konkretnych elementów programu (funkcje, struktury, klasy, moduły, itp.). Programowanie kontraktowe jest związane z programowaniem obiektowym.

Historia

Określenie to zostało wprowadzone przez Bertranda Meyera, w odniesieniu do projektu jego języka programowania Eiffel, w artykułach, począwszy od roku 1986, a także w edycjach z lat 1988 i 1997 swojej książki pod tytułem "Object-Oriented Software Construction". W 2004 roku przyznano Eiffel Software znak towarowy Design by contract, W związku z tym, w źródłach anglojęzycznych można się również spotkać z określeniami Programming by contract i Contract programming.

Założenia

Programowanie zakłada, że elementy programu powinny odnosić się do siebie na zasadzie kontraktów, czyli:

  • Każdy element powinien zapewniać określoną funkcjonalność i wymagać ściśle określonych środków do wykonania polecenia.
  • Klient może użyć funkcjonalności, o ile spełni zdefiniowane wymagania.
  • Kontrakt opisuje wymagania stawiane obu stronom.
  • Element zapewniający funkcjonalność powinien przewidzieć sytuacje wyjątkowe, a klient powinien je rozpatrzyć. W niektórych językach wychwytywanie wyjątków ma charakter obowiązkowy (np. Java), inne pozostawiają programiście wybór.

Sprawdzenie danych wejściowych i wyjściowych

Głównym mechanizmem programowania kontraktowego jest weryfikacja danych przesyłanych do funkcji i jej wyniku. Sprawdzanie danych wejściowych jest bardzo powszechną praktyką, stosowaną nawet w językach nie posiadających specjalnie przygotowanych do tego konstrukcji. Znacznie rzadsza jest kontrola zwracanej wartości. Konstrukcję do sprawdzenia danych wejściowych i wyjściowych zapewnia między innymi język D:

double divide(double dividend, double divisor)
in{
  assert(divisor != 0);
}
out (result){
  assert(result < 10);
}
body{
  return dividend/divisor;
}

Funkcja ta najpierw sprawdzi czy drugi argument jest równy zeru, jeśli tak, zwróci wyjątek; jeśli nie, podzieli pierwszy argument przez drugi. Następnie sprawdzi, czy wynik jest mniejszy od 10. Jeśli okaże się mniejszy, funkcja zwróci wartość. W przeciwnym wypadku zwróci wyjątek.

Za szczególny przypadek kontroli danych wyjściowych można uznać również test jednostkowy.

Języki programowania wspierające programowanie kontraktowe.

Oprócz tego, dla niektórych języków programowania stworzono biblioteki zapewniające tego typu funkcjonalność.

Przypisy

  1. Za pomocą biblioteki zewnętrznej Quid Pro Quo. https://github.com/sellout/quid-pro-quo