250 likes | 386 Views
Afrunding/lidt af hvert. Generelt om kontrakter Kontrakter på modelnivaeu Kontrakter uden JML Kontrakter og test. Design by Contract. Separation of Concerns: Ansvarsfordeling via præcise kontrakter, dvs. formelle specifikationer Forudsætning for (delvis) automatisk verifikation
E N D
Afrunding/lidt af hvert Generelt om kontrakter Kontrakter på modelnivaeu Kontrakter uden JML Kontrakter og test KbP/seminar3: miscAboutContracts
Design by Contract • Separation of Concerns: • Ansvarsfordeling via præcise kontrakter, dvs. formelle specifikationer • Forudsætning for (delvis) automatisk verifikation • Fortræk Delegation frem for arv (løs kobling). Hvis arv bruges, så substitutionsprincippet. • ”find what varies and encapsulate it” KbP/seminar3: miscAboutContracts
Kontrakter på mange niveauer • Modelniveau (UML-niveau) • relationer med begrænsninger • Interfaceniveau • funktionelle specifikationer (pre og post) og klasseinvariant (typeinvariant) • Klasseniveau • repræsentationsinvariant • Subklasseniveau • extends, implements, substitutionsprincippet (guarded post conditions) • Metodeniveau • programudsagn (specielt løkkeinvarianter) KbP/seminar3: miscAboutContracts
Kontrakter på modelniveau • En klassemodel tjener (mindst) to formål • Begrebsmodel: kontrakt mellem kunde og leverandør • Specifikationsmodel: kontrakt mellem udviklere KbP/seminar3: miscAboutContracts
Specifikationsmodel: Talkmore A/S 1 * * Ejer Abonnement Transaktion 1 Modtager Opkald * MMO MMS SMS Indbetaling Hvad er der af kontrakter her? Billede Video Lyd KbP/seminar3: miscAboutContracts
Specifikation af interfaces • Specifikationen er kontrakten: • Den skal beskrive HVAD enhver implementation kan gå ud fra og skal opfylde • Den skal være præcis og utvetydig – men med en masse betydning KbP/seminar3: miscAboutContracts
A side:Programmér altid mod interfaces • ArrayList l = new ArrayList(); • List l = new ArrayList(); • List l = ListFactory.createList(); class ListFactory{//FactoryMethod public static List createList(){ return new ArrayList(); } } Altid??? KbP/seminar3: miscAboutContracts
Factory class ListFactory{//FactoryMethod public static List createList(){ return new ArrayList(); } } • Create-metoder kan specificeres i et interface (skal etablere klasse (type) -invarianten). • Det kan constructors ikke. • Men statiske metoder kan ikke være i interfacet…? KbP/seminar3: miscAboutContracts
http://stackoverflow.com/questions/6129026/effective-java-by-joshua-bloch-item1-static-factory-methodhttp://stackoverflow.com/questions/6129026/effective-java-by-joshua-bloch-item1-static-factory-method IFTest KbP/seminar3: miscAboutContracts
Niveauer af formalisme for interface-specifikation • Signatur • Navn, returtype og parameterliste for hver metode (sprogunderstøttet) – “gæt en spec.” • Uformel • Beskrivelse i naturligt sprog. • Pre-Post i naturligt sprog • Pre-condition: hvad implementationen kan antage om tilstand og parametre • Post-condition: hvad klienten kan antage om ny tilstand, parametre og returværdi • Formel • Pre-Post udtrykkes i en formel (matematisk) notation • Værktøjsunderstøttelse: • I sproget (Eiffel, Spec#) • Preprocessor (JML, iContract, jContract mfl.) • Bibliotek: CodeContracts http://docs.oracle.com/javase/6/docs/api/ String - substring KbP/seminar3: miscAboutContracts
Eksempel: Bag • A container (of numbers) • A number may occur more than once • Methods • Add a number • Remove one occurrence of a number • Remove all occurrences of a number • Count how many times a number occurs • Size KbP/seminar3: miscAboutContracts
Signatur-specifikation Gæt en post-betingelse? interface Bag { void add(int x); void removeOne(int x); void removeAll(int x); int noOf(int x); int size(); } Kun syntakskontrol KbP/seminar3: miscAboutContracts
Uformel specifikation Hvad ved vi ikke her? interface Bag// contains numbers { // invariant: size()>=0 void add(int x); // add x void removeOne(int x); // remove one occurrence of x void removeAll(int x); // remove all occurrences of x int noOf(int x); // return number of occurrences of x int size(); // return total number of numbers } Gæt en pre-betingelse? KbP/seminar3: miscAboutContracts
PRE- & POST-specifikation interface Bag // s: a container of numbers { // invariant: size()>=0 void add(int x); // pre: none // post: s contains one more x than before void removeOne(int x); // pre: none // post: if x occurred in s before, s containsone x // less than before; else, s remained unchanged void removeAll(int x); // pre: none // post: s does not contain any x’s int noOf(int x); // pre: none // post: return number of occurrences of x’s in s int size(); // pre: none // post: return total number of numbers in s } KbP/seminar3: miscAboutContracts
Bag – formel spec. -1 interface Bag // s: a multiset of numbers // s = Ø initiallly { void add(int x); // pre: none // post: s = sold [x] void removeOne(int x); // pre: none // post: s = sold – [x] void removeAll(int x); // pre: none // post: #x(s)=0 and for yx, #y(s) = #y(sold) Frame rule KbP/seminar3: miscAboutContracts
Bag – formel spec. -2 // s: a multiset of numbers // s = Ø initiallly int noOf(int x); // pre: none // post: s = sold and noOf = #x(s) int size(); // pre: none // post: s = sold and size = |s| } Frame rules KbP/seminar3: miscAboutContracts
Værktøjsunderstøttet • Bag i henhold til DbC • Bag i JML eller i CodeContracts eller i Eiffel eller i… • Overlades til en (ekstra) øvelse KbP/seminar3: miscAboutContracts
Øvelse • LottotalsGenerator • Specificer en lottotalsgenerator, som kan generere tilfældige tal i et interval. • Det samme tal må ikke komme to gange. • Vælg selv niveauet af formalisme i specifikationen Lottotal.ppt KbP/seminar3: miscAboutContracts
Kontrakter uden værktøj • Exceptions til check for preconditions • Lav en Assertion-klasse (til brug ved debugning): public class Assertion { public static boolean NDEBUG = true; private static void printStack(String why) { Throwable t = new Throwable(why); t.printStackTrace(); System.exit(1); } public static void assert(boolean expression, String why) { if (NDEBUG && !expression) printStack(why); } } KbP/seminar3: miscAboutContracts
Java (1.4 og højere): assert • Preconditions: public int pop() { // precondition: assert !isEmpty() : "Stack is empty"; return stack[--num]; } Tilsvarende mekanisme i C# KbP/seminar3: miscAboutContracts
Postconditions: public void push(int element) { // precondition: assert num<capacity : "stack is full"; int oldNum = num; stack[num++] = element; // postcondition: assert num == oldNum+1 && stack[num-1] == element : "problem with counter"; } KbP/seminar3: miscAboutContracts
Invariant: Lav en metode på alle klasser: private boolean inv() { return (num >= 0 && num < capacity); } Alle public metoder og constructors har dette check umiddelbart før return: assert inv(); KbP/seminar3: miscAboutContracts
Kontrakter og test • Kontrakter specificerer moduler • Kontrakter er dokumentation – også af test • Kontrakter er en del af koden! Og vedligeholdes sammen med koden! • Kontrakter specificerer tests • Ved brug af værktøjer som JML er testdriverne en del af koden KbP/seminar3: miscAboutContracts
XP o. lign. • Skriv testen før koden: • Kræver dyb forståelse af problemet • Kræver velgennemtænkte interfaces • Testdriveren bliver en specifikation! • Så hvorfor ikke skrive specifikationen først? KbP/seminar3: miscAboutContracts
Fordele: Mere systematisk design Klarere design Simplere design Bedre problemforståelse Bedre dokumentation Bedre testet Simplere debugning Ulemper (er der nogen?): Tager tid Er svært? (i hvert fald for i dags gennemsnitsprogrammører) Falsk tryghed? Manglende sprogunderstøttelse Fejl i kontrakten? Bedst til sekventielle programmer Diskussion:Kan det svare sig? KbP/seminar3: miscAboutContracts