středa 17. ledna 2007

Programovaní kontraktem, Design By Contract

Programování kontraktem nebo také nazývané Design by contract je způsob návrhu softwarových komponent. Každá komponenta nebo objekt, říkejme tomu podle libosti, má vždy nějaký kontrakt. Kontrakt popisuje vstup, výstup a invarianty (neměnné podmínky) dané komponenty. Každý klient, který s komponentou spolupracuje pak daný kontrakt akceptuje, prostým faktem, že komponentu používá.

  
public class Auto {
  private int maxHmotnost; //maximalni hmotnost auta
  private int hmotnost; //aktualni hmotnost
  
  public class Auto(int maxHmotnost) {
    this.maxHmotnost = maxHmotnost;
  }
  
  public int nalozit(int hmotnostNaklad) {
    if(hmotnostNaklad < 1 
          || hmotnostNaklad > maxHmotnost) {
        throw new IllegalArgumentException();
    }
    
    int novaHmotnost = hmotnost + hmotnostNaklad;
    if(novaHmotnost > maxHmotnost) {
      throw new IllegalArgumentException();
    }
    
    this.hmotnost = novaHmotnost;
    return this.hmotnost;
  }
} 
 

Kontrakt třídy Auto je definován následovně. Neměnnou podmínkou je maximální hmotnost auta, ta se nikdy nemění. Kontrakt dále definuje v rámci metody nalozit rozsah vstupního argumentu, který nesmí být: menší nebo rovna nule a větší než maximální hmotnost a garantuje, že za těchto podmínek nebude vrácená nová hmotnost větší než maximální hmotnost auta.

Naše třída má kontrakt nadefinovaný explicitně, to znamená, že obsahuje nutné kontroly, které dbají nad jeho dodržováním. To zabraňuje chybovému chování v případě, že klient kontrakt nedodrží. Například by klient odlehčil auto zápornou hmotností a nebo by jej naopak přeložil.

Design By Contract je založen na tom, že všechny komponenty svůj kontrakt definují explicitně. Tím je zaručeno, že jeho porušení vede přerušení zpracování a nebo nevykonání operace. Z pohledu vývoje je tohle chování velice patřičné, protože jakékoliv porušení kontraktu (nesprávné použití komponenty) vede k vyhození výjimky a tím pádem k přerušení a je signálem nesprávného použití případně jiných problémů.

Vlastní kontrolu kontraktu lze v Jave udělat několika způsoby. Například testem jako je to v metodě nalozit a nebo použitím klíčového slova assert (Java 1.4). Další možností je použítí anotací, jako to děla například framework Contract4J a nebo Spring contracts.

Pokud vás Design By Contract nezuajal a nebo si myslíte, že jste něco nechytli, apk vřele doporučuji dát poslední šanci rozhovoru Design by Contract: A Conversation with Bertrand Meyer, Part II.