Abstraheren van modellen Geert Delanote 7 maart 2005 Geert.Delanote@cs.kuleuven.ac.be Software Development Methodology 1
Inhoudstafel Motivatie Denkpistes Software Development Methodology 2
Motivatie Verslag vorige vergadering Discussiepunt Belang van verbanden tussen verschillende modellen op eenzelfde (hoog) abstractieniveau; problemen met uitdrukking hiervan (UML volstaat niet). Vertrekpunt Observatie dat PIM-modellen te complex worden - UML is niet expressief genoeg Transformatie naar PSM-modellen (semi-)automatisch? Onderzoek Niet afgerond! Software Development Methodology 3
Motivatie Denkpistes : Reïficatie van methodes Verbanden tussen methodes - Reïficatie van toestanden Complexe hiërarchieën Financial case study Software Development Methodology 4
Inhoudstafel Motivatie Denkpistes Reïficatie van methodes Verbanden tussen methodes - Reïficatie van toestanden Complexe hiërarchieën Software Development Methodology 5
Case 1 : Reïficatie van methodes Gegeven : een klasse van boeken met een event om boeken uit te lenen Book +loan(period:duration):void met een query om het aantal uitleningen op te vragen Book +loan(period:duration):void +nbloans():natural 1 * Loan - period : DURATION en met queries om het tijdstip van de laatste uitlening en de gemiddelde uitleenperiode op te vragen Software Development Methodology 6
Case 1 : Reïficatie van methodes Doel : De klasse Book op PIM niveau voorstellen en specificeren De specificatie transformeren naar PSM niveau Book +loan(period:duration):void +nbloans():natural +latestloan():date +avgloanperiod():duration We voeren de # - operator in obj#event() Deze expressie geeft de verzameling van alle voorkomens op het object obj van de event event() terug Software Development Methodology 7
Case 1 : Reïficatie van methodes Context Book :: nbloans() Post: result = card(this#loan()) Context Book :: latestloan() Pre: not(this#loan()->isempty) --- alternatief : Pre: nbloans() > 0 Post: result = max((this#loan())->executiontime) Context Book Inv: latestloan() <= now Context Book :: avgloanperiod() Post: result = avg((this#loan())->period) Context Book Constraint: for each loan1, loan2 in this#loan() : if (loan1 loan2) then (loan1->executiontime + loan1->period) <= loan2->excecutiontime (loan2->executiontime + loan2->period) <= loan1->excecutiontime Software Development Methodology 8
Case 1 : Reïficatie van methodes Transformatie PIM -> PSM PSM 1 : Reïficatie van de event loan PSM 2 : Niet-reïficatie van de event loan PSM 3 : Automatisch? Software Development Methodology 9
PSM 1 : Reïficatie van de event loan Method class cfr. Assocation class Elke instantiatie van de method class is een uitvoering van de event loan() (en omgekeerd) Elke karakteristiek van een event is ook een karakteristiek van objecten van de klasse - bv. ExecutionTime -> CreationTime Elke parameter van de event is een property van de klasse Software Development Methodology 10
PSM 1 : Reïficatie van de event loan Context Book :: nbloans() Post: result = card(this->loan) Context Book :: latestloan() Pre: not(this->loan->isempty) Post: result = max((this->loan)->creationtime) Context Book Inv: latestloan() <= now Context Book :: avgloanperiod() Post: result = avg((this->loan)->period) Context Book Constraint: for each loan1, loan2 in this->loan : if (loan1 loan2) then (loan1->creationtime + loan1->period) <= loan2->creationtime (loan2->creationtime + loan2->period) <= loan1->creationtime Software Development Methodology 11
PSM 1 : Reïficatie van de event loan Vaststellingen De transformatie kan automatisch gebeuren Dit PSM is tegelijk een PIM - NATURAL : verschillende transformaties naar een programmeertaal mogelijk - Verschillend bereik mogelijk : long, int, - Taalafhankelijke verschillen : ulong in C# vs long in Java - CreationTime Software Development Methodology 12
PSM 2 : Niet-reïficatie van de event loan Invoeren properties Notatie : (obj#event())@current Twee gevallen : 1. Het resultaat van de query kan bepaald worden op basis van het vorige resultaat en het effect van deze event 2. Het resultaat van de query kan niet bepaald worden zoals in geval 1 Software Development Methodology 13
Transformatie van nbloans() Gegeven : (Geval 1) Context Book :: nbloans() Post: result = card(this#loan()) Context Book : loan() Pre: - Post: - Stap1: - Zet de query om in een property - Maak van de resultclause een postconditie bij loan() - Geef de property een initiële waarde (card(empty set) == 0) Context Book :: property NATURAL nbloans Initial value : 0 Semantics : card(this#loan()) Context Book : loan() Pre: - Post: this.nbloans = card(this#loan()) Software Development Methodology 14
Transformatie van nbloans() Stap2: Zonder de huidige uitvoering van de methode loan() af Context Book : loan() Pre: - Post: this.nbloans = card( (this#loan())@pre union {(this#loan())@current} ) Stap3: card(x union Y) == card(x) + card(y) Context Book : loan() Pre: - Post: this.nbloans = card( (this#loan())@pre ) + card( {(this#loan())@current} ) Stap4: - Cardinaliteit van een set met 1 element is 1 - Cardinaliteit van de alle uitvoeringen behalve de huidige = de waarde van de instantievariabele voor de uitvoering van de methode Context Book : loan() Pre: - Post: this.nbloans = this.nbloans@pre + 1 Software Development Methodology 15
Transformatie van latestloan() Gegeven : (Geval 1) Context Book :: latestloan() Pre: this#loan()->notempty Post: result = max((this#loan())->executiontime) Context Book : loan() Pre: - Post: - Stap1: Zet de preconditie om in een booleaanse property Context Book :: property BOOLEAN loanisexecuted Initial value : false Semantics : this#loan()->notempty Context Book :: latestloan() Pre: loanisexecuted Post: result = max((this#loan())->executiontime) Software Development Methodology 16
Transformatie van latestloan() Stap2: - Zet de query om in een property - Maak van de resultclause een postconditie bij loan() - Geef de property een initiële waarde (max(empty set) == undefined) Context Book :: property DATE latestloan Initial value: undefined Pre: loanisexecuted Semantics: max((this#loan())->executiontime) Context Book : loan() Pre: - Post: this.latestloans = max((this#loan())->executiontime) Stap3: Zonder de huidige uitvoering van de methode loan() af Context Book : loan() Pre: - Post: this.latestloans = max( ((this#loan())@pre)->executiontime union {((this#loan())@current)->executiontime} ) Software Development Methodology 17
Transformatie van latestloan() Stap4: if (X->isEmpty) then max(x union Y) == max(y) else max(x union Y) == max{max(x), max(y)} Context Book : loan() Pre: - Post: this.latestloan = if ((((this#loan())@pre)->executiontime)->isempty) then max({((this#loan())@current)->executiontime }) else max{ max(((this#loan())@pre)->executiontime), max({((this#loan())@current)->executiontime }) } Stap5: - Maximum van een set met 1 element is dat element - Maximum van alle uitvoeringen behalve de huidige = de waarde van de instantievariabele voor de uitvoering van de methode - Vervang de booleaanse expressie door de property Context Book : loan() Pre: - Post: this.latestloan = if (not(this.loanisexecuted@pre)) then ((this#loan())@current)->executiontime else max{this.latestloan@pre, ((this#loan())@current)->executiontime} Software Development Methodology 18
Transformatie van latestloan() Stap6: De opgevraagde karakteristieken van de methode worden ingevuld Context Book : loan() Pre: - Post: this.latestloan = if (not(this.loanisexecuted@pre)) then now else max{ this.latestloan@pre, now} Stap7*: Vereenvoudig de postconditie verder. (latestloan@pre < now) Context Book : loan() Pre: - Post: this.latestloan = if nbloans()@pre = 0 then now else now en dus: Context Book : loan() Pre: - Post: this.latestloan = now Software Development Methodology 19
Transformatie van avgloanperiod() Gegeven : (Geval 2) Context Book :: avgloanperiod() Post: result = avg((this#loan())->period) Context Book : loan() Pre: - Post: - Stap1: Herschrijf de functie in een samenstelling van functies om zo tot een Geval 1 te komen. Context Book :: avgloanperiod() Post: result = if this#loan()->isempty() (of : card(this#loan()) = 0) then 0 else sum((this#loan())->period) / card(this#loan()) Software Development Methodology 20
Transformatie van avgloanperiod() Stap2: - Zet de query om in properties - Maak voor iedere property een postconditie bij loan() - Geef de properties een initiële waarde(card(empty set)= 0; sum(empty set)= 0) Context Book :: property NATURAL nbloans Initial value: 0 Semantics: card(this#loan()) Context Book :: property DURATION totalloanperiod Initial value: 0 Semantics: sum((this#loan())->period) Context Book :: avgloanperiod() Post: result = if nbloans = 0 then 0 else totalloanperiod / nbloans Context Book : loan() Pre: - Post: this.nbloans = card(this#loan()) Post: this.totalloanperiod = sum((this#loan())->period) Software Development Methodology 21
Transformatie van avgloanperiod() Stap3: Ga verder met Stap2 uit het algoritme met gegeven Geval1 voor iedere postconditie. Context Book : loan() Pre: - Post: this.nbloans = this.nbloans@pre +1 Post: this.totalloanperiod = this.totalloanperiod@pre + period Software Development Methodology 22
Algoritme Stap 1: Herhaal voor elke query : Zet de precondities om in booleaanse properties Stap 2: Herhaal voor elke query : Als het resultaat van de query niet kan bepaald worden op basis van het vorige resultaat en de huidige uitvoering, dan wordt de operatie zo opgesplitst in deeloperaties zodat het resultaat van elk van de deeloperaties wel kan bepaald worden op basis van het vorige resultaat en de huidige uitvoering Stap 3: - Maak de nodige properties aan (zonder dubbels, i.e. properties met dezelfde semantische betekenis, aan te maken!) - Laat de query het resultaat in functie van die properties teruggeven Stap 4: (?) Reduceer het aantal properties. Software Development Methodology 23
Algoritme Stap 5: Maak voor iedere property een postconditie bij elke event die voorkomt in de semanticsclause Stap 6: Herhaal voor elke property : Als er een (semantisch) zinvolle waarde kan gegeven worden, dan initialiseer de property, anders is de property initieel undefined Als de property niet altijd defined is dan wordt er een preconditie, die definieert wanneer de property undefined is, aan de property toegevoegd. Stap 7: Herhaal voor elke postconditie : Zonder het huidige voorkomen van de event af Stap 8: Vervang de huidige postconditie f( {vroegere voorkomens} union {huidige voorkomen} ) door g( f( {vroegere voorkomens} ), f( {huidige voorkomen} ) ) Stap 9: f({huidige voorkomen}) is triviaal f({vroegere voorkomens}) = f@pre = property@pre Stap 10: Vereenvoudig de postconditie - Vul karakteristieken in (vb. ((this#event())@current)->executionttime = now) - Vereenvoudig expressies (vb. max(0,1) = 1) Software Development Methodology 24
Inhoudstafel Motivatie Denkpistes Reïficatie van methodes Verbanden tussen methodes - Reïficatie van toestanden Complexe hiërarchieën Software Development Methodology 25
Case 2 : Verbanden tussen methodes (1) Gegeven een klasse van boeken met dezelfde events en queries Een extra event return() - Een boek kan pas teruggebracht worden als het uitgeleend was - Een uitgeleend boek kan niet uitgeleend worden Software Development Methodology 26
Case 2 : Verbanden tussen methodes (1) Software Development Methodology 27
Case 2 : Verbanden tussen methodes (1) Software Development Methodology 28
Case 2 : Verbanden tussen methodes (1) Context Book :: nbloans() Post: result = card(this#loan()) Context Book :: latestloan() Pre: not(this#loan()->isempty) Post: result = max((this#loan())->executiontime) Context Book Inv: latestloan() <= now Context Book :: avgloanperiod() Post: let returnedloans = {loan this#loan() loan.return()->notempty} in result = avg({{period in DURATION loan returnedloans : loan.return()->executiontime loan->executiontime}}) Context Book Constraint: for each loan in this#loan() : {l this#loan() l->executiontime < loan->executiontime and if (l.return()->notempty) then loan->executiontime<l.return()->executiontime else true }->isempty Software Development Methodology 29
Case 2 : Verbanden tussen methodes (1) PSM 1 : Reïficatie van de events PSM 2 : Niet-reïficatie van de events uit te werken Software Development Methodology 30
Case 2 : Verbanden tussen methodes (2) Gegeven een klasse van bankrekeningen events om geld te storten, af te halen, over te schrijven Account + transfer(amount:moneyamount,dest:account):void + deposit(amount:moneyamount):void + withdraw(amount:moneyamount):void Abstracte methode Account + <abstract> transaction(amount:moneyamount):void + transfer(dest:account):void + deposit():void + withdraw():void Software Development Methodology 31
Inhoudstafel Motivatie Denkpistes Reïficatie van methodes Verbanden tussen methodes - Reïficatie van toestanden Complexe hiërarchieën Software Development Methodology 32
Hiërachieën Software Development Methodology 33
Property + constraint Context Account :: property MONEYAMOUNT balance Initial value: 0 Semantics: sum( (this#deposit())->amount union (-1)*(this#withdraw())->amount) ) Context Book Inv: balance > 0 Programmeren : hoe dwingen we de constraint af? Nominaal (precondities) Totaal Defensief (uitzonderingen) Op database niveau Software Development Methodology 34