De presentatie wordt gedownload. Even geduld aub

De presentatie wordt gedownload. Even geduld aub

Richtlijnen Specificaties Multiple inheritence

Verwante presentaties


Presentatie over: "Richtlijnen Specificaties Multiple inheritence"— Transcript van de presentatie:

1 Richtlijnen Specificaties Multiple inheritence
H9: Klasse Ontwerp Richtlijnen Specificaties Multiple inheritence

2 SchetsPlus... doe ik het goed ?

3 Hoe maak ik goede klassen ?
We gaan kijken naar: algemene ontwerp-richtlijnen software metric Complement: style-gidsen, tips, best practices, kookboeken, enz. Sun’s Java Coding Style Guide Ambler, the Elements of Java Style

4 Richtlijnen Structuur is belangrijk, wat je niet wil: Optimaliseer :
complex  fouten, onderhoudkost star Optimaliseer : encapsulatie inheritence cohesie koppeling Encapsulatie  dat een “module” een eenvoudig interface naar buiten toe definieert  dus houd je de implementatie gescheiden. Voordeel: De interface is abstractie  makkelijker om te begrijpen Vervangbaar implementatie Inheritence  laat je functionaliteiten hergebruiken. Een “module” is cohesief  als zijn de functionaliteiten die het aanbiedt sterk aan elkaar gerelateerd zijn. Voorbeeld: Persoon, berekenIdealeGewicht, berekenIdealeLengte  cohesief Persoon, als (1), + getVrienden  minder cohesief Persoon, als (1), + addInAdresBoek  niet cohesief

5 addInAdresBoek(aboek)
Cohesie Een “module” is cohesief als het een set van sterk aan elkaar gerelateerd “functionaliteiten” aanbiedt. Persoon getGewicht() getLengte() Persoon getGewicht() getLengte() getVrienden() Persoon getGewicht() getLengte() addInAdresBoek(aboek)

6 Koppeling Er is een koppeling tussen modules A en B als een van de andere afhankelijk is. Voorbeelden: datakoppeling globale-var koppeling f() { ... u.g(x) ... } m1,m2 via een static attribuut C1, C2 via een package-private attribuut

7 Koppeling Pathologisch in C++ heb je ook friends. Mixer
if (drank.zoet() > 10) { drank.water++ ; drank.roer() ; } Drank - suiker : int - water : int + zoet() : int + roer() De verleiding is groot om zoet nu gewoon publiek te maken.

8 Koppeling In OO ook door:
Associatie / navigatie Verse objecten in methode Via inheritence Vaak spanningveld tussen koppeling en de andere aspecten: maak A subklasse van B  koppeling verhoogt cohesie met delegatie  koppeling

9 Inheritence koppeling
Drank mixMetMelk() // concreet abstract mix() Persoon getKinderen() Thee Klant Koffie

10 Demeter Principe Ian Holland, “Zorg dat objecten alleen met vrienden praten.” Delegeer: Vliegtuig bagageGewicht() : int Persoon naam heeft * Tas gewicht vervoert * Persoon naam tassenGewicht() Vliegtuig bagageGewicht() : int heeft * Tas gewicht vervoert * ten koste van de cohesie van Persoon.

11 Connascance Page-Jones, 1992. Letterlijk: tegelijkertijd geboren.
Page-Jones: Klassen C en D zijn connascent als het mogelijk is om C aan te passen die een aanpassing van D dwingt.  koppeling! Voobeeld: Vrouw -- Man Klasse Vrouw, met +werken() Klasse Man, met +opKinderenPassen()

12 Uit project management perspectief
Software metriek  complexiteit indicatoren Om strategisch te beslissen dat bepaalde delen van de software een risico factor zijn, en dat reorganisatie nodig is. Voor programmeurs ook nuttig als richtlijnen.

13 Voorbeeld Metriek : + Uit te rekenen (en goedkoop)  tools! - abstract
Zoals, #regels Nog meer? Traditionele metrieken Halstead McCabe Oviedo OO metriek “de” metriek bestaat niet  ze zijn allemaal indicatoren. Voorbeeld tools: loc, jhawk, metrics

14 Halstead Complexiteit: moeite om code te lezen E = D * V
x = x + x ; x++ x = x + y ; z++ Belangrijk in Halstead: meerdere keren gebruikt van hetzelfde woord verlaagt D. Anders gezegd, een boek die met minder vocabulaire geschreven wordt is gezien als makkelijker te lezen. (alleen ter info)

15 McCabe Het aantal lineair onafhankelijke paden in je programma.
int P() { if (...) return 100 else return 0 } 1 2 Pad s en t zijn lineair onafhankelijk als t bevat minstens 1 pijltje die nog niet in s is (of andersom). Control Flow Graph (CFG)

16 McCabe 4 1 3 2 5

17 Oviedo Splits programma in sequentiële blokken Voorbeeld:
interacties tussen elementen in een blok voegen niets aan complexiteit. afhankelijkheden tussen blokken wel. Voorbeeld: P(int x, int y) { if (y>0) x = 0 ; else x = 1 ; return x } DF = Data Flow complexiteit (y>0) ; x = 0 (~y>0) ; x = 1 DF = 2 DF = 2 return x DF(P) = 6 DF = 2

18 OO metriek Voor OO willen we ook indicatie hebben over structurele complexiteit van je klassen. Chen & Lu, 1993: Encapsulatie Koppeling Inheritence Cohesie Recenter: Mao & Jiang, 2008.

19 Encapsulatie (P) Idee:
Methode met minder argumenten is abstracter Simpel vs complex parameters, bijvoorbeeld: P = som van de complexiteit van de argumenten (van pub. methodes) in C. Type Complexiteit waarde boolean, int double 2 object 6-9

20 Koppeling (Cp) Idee Cp = som van boven. C gebruikt D  1x koppeling
C wordt door D gebruikt  1x koppeling wederzijde koppeling  lastig  telt als extra Cp = som van boven.

21 Cohesie Co Hoe weten we welke methode bij elkaar horen?? Idee: methodes met dezelfde type signatuur horen vaak bij elkaar. Chen en Lu  ook “sub” signatuur. m1(int,Vervoer) ~ m2(Vervoer,int,Persoon) Vervoer + versnel(real) + addPassagier(Persoon) + swapPassagiers(Persoon, Persoon) + addPassagiers (Collection<Persoon>) Co = G / N = 0.75

22 Inheritence H Inheritence is goed (code hergebruik), maar je code wordt ook minder expliciet  in zekere zin ook fout gevoelig. H is een meting van inheritence complexiteit. Som van: # methodes inheritence afstand # direct superklassen. # subklassen Minder expliciet  impliciet invloed van supperklassen Som van : # methodes, eigen en geerfd verre superklasse zorgt voor verassing  inheritence afstand multiple-inh. is lastig  # direct superklassen. je klasse creert ook impliete invloed op al zijn subklassen  # subklassen

23 JHawk Halstead Bug Metric : hoeveel bugs je nog hebt in je programma.
Origineel: e^(2/3) / maar recent experimenten suggereren vol / 3000 The Maintainability Index (MI) is a set of polynomial metrics developed at the University of Idaho, using Halstead's effort and McCabe's cyclomatic complexity, plus some other factors relating to the number of lines of code (or statements in the case of JHawk (see above)) and the percentage of comments. The MI is used primarily to determine if code has a high, medium or low degree of difficulty to maintain. It is language independent and was validated in the field by Hewlett-Packard (HP). HP concluded that modules with a MI less than 65 are difficult to maintain, modules between 65 and 85 have reasonable maintainability and those with MI above 85 have excellent maintainability Actually there are three measures: MIwoc: Maintainability Index without comments MIcw: Maintainability Index comment weight MI: Maintainability Index = MIwoc + MIcw The general formulae for MI is the following:         MIwoc = * ln(aveV) * aveG * ln(aveLOC)         MIcw = 50 * sin(sqrt(2.4 * perCM))         MI = MIwoc + MIcw Where         aveV = average Halstead Volume (CMT++/CMTJava´s V) per module          aveG = average extended cyclomatic complexity (CMT++/CMTJava´s v(G) ) per module          aveLOC = average count of lines (CMT++/CMTJava´s LOCphy) per module  perCM = average percent of lines of comments per Module

24 Klasse specificatie Meer kun je niet met klasse diagram uitdrukken...
Videotheek Minderjarig bonus Klant Naam Leeftijd DVD titel leeftijdgrens leent * < is verantwoordelijk voor Meer kun je niet met klasse diagram uitdrukken... Een klant is een mj als zijn/haar leeftijd ≤ 18 De klant die voor een mj verantwoordelijk is, is zelf geen mj. .

25 Klasse invariant Een klasse invariant van C is een constraint op de attributen van de objecten van C. Anders zit een object in een verkeerde/onveilig toestand. Het gaat over de stabiele toestand van een object (dus niet als een operatie nog bezig is met het object). Minderjarig Octo 30 Minderjarig Bob 10 De leeftijd van een mj is  18.

26 Klasse invariant Maar indirect gaat het eigenlijk ook over associaties... Hoe belangrijk?  erg belangrijk. DVD Sneeuwwit 0+ leent Minderjarig Bob 10 DVD Star Trek 10+ In het algemeen, de invarianten van de klassen van onze app specificeren waneer de objecten een consistent systeem vormen. DVD Kill Bill 12+

27 Hoe druk je dat uit? Met “predicaten” zoals in Logica :
“Object Constraint Language” (OCL)  onderdeel van UML. (forall x : Minderjarig  x.leeftijd  18) context x : Minderjarig inv: x.leeftijd  18

28 Navigatie in OCL context dvd : DVD
Klant Naam Leeftijd DVD titel leeftijdgrens leent > * lener dvds context dvd : DVD inv: dvd.lener.leeftijd  dvd.leeftijdgrens context x : Klant inv: x.leeftijd  x.dvds.leeftijdgrens levert een verzameling terug!

29 Collecties in OCL Zoals Set en Sequence Operatoren zoals:
size(), sum(), isEmpty() includes(x) forAll(...), exists(...), select(…) Eigenaardig syntax: u  isEmpty() u  includes(x)

30 Voorbeeld context x : Klant inv: x.leeftijd  x.dvds.leeftijdgrens
Naam Leeftijd DVD titel leeftijdgrens leent * lener dvds context x : Klant inv: x.leeftijd  x.dvds.leeftijdgrens inv: x.dvds  forall (dvd | x.leeftijd  dvd.leeftijdgrens)

31 Filter  select operatie
Klant Naam Leeftijd DVD titel premium : boolean leent * lener dvds Je mag slechts één permium DVD lenen. context x : Klant inv: x.dvds  select (dvd | dvd.premium = true) size() ≤ 1

32 Methode specificeren declaratief !
Pre/Post spec, pseudo code, geen OCL. Klant inschrijf() leen(d) getLeenLimiet() declaratief ! Inschrijf() dient de collectie van gelende dvds op leeg te zetten forall x : Klant { true } x.inschrijf() { x.dvds =  } context x : Klant:: inschrijf() pre: true post: x.dvdsisEmpty()

33 Mix in specificatie met “query”
Klant inschrijf() leen(d) getLeenLimiet() Je mag niet meer dan je limiet lenen. markeer als ‘isQuery’, maar alleen als side-effect vrij! context x : Klant:: leen(d) pre: x.dvds  size() + 1 ≤ x.getLeenLimiet() post: x.dvds =  insert(d) Gelijkheid over set in OCL. Als U en V set zijn, U=V vergelijk of deze twee sets dezelfde elementen hebben. Als de elementen objecten zijn, dan worden ze op object-ID level vergelijk; dus niet op inhoud.

34 Multiple inheritence Product ID Naam Prijs GroteBestelling koopGroot(n) ImportGoed invoerBelasting() Koffie Krachtig ! Je kunt makkelijk verschillende features erven. Talen met MI  C++. Eiffel, Python Om uit te kijken  diamantprobleem Als je toch in Java wil implementeren …

35 Feature clash… Geen echte issue. Eiffel  renaming
Werknemer werk() Artiest werk() Welke werk() wordt bedoelt in Muzikant ? (soms de ene soms de andere) Muzikant Geen echte issue. Eiffel  renaming class Muzikant inherit Werknemer rename werk as werk1 Artiest rename werk as werk2 feature end

36 Diamantprobleem Persoon Naam Leeftijd Werknemer Artiest Muzikant Een muzikant kan in principe 2x namen en leeftijden erven. leefdtijd  onzinnig  merge tot 1x naam  misschien wil je een echte naam en een artiestnaam. Ambigu  compiler kan deze niet zelf beslissen…

37 Inheritence vs associatie
W Artiest Naam Werk() Artiest Naam Werk() Muzikant Muzikant MI Delegatie Feature erven Ja Is M ook een A ? Nee

38 Simuleren met assoc + interface
Gedoe .. Als MI essentieel in je ontwerp is, implementeer ook in een MI taal. Anders haal MI uit je ontwerp. Andere overweging: persistence. W Artiest Naam Werk() Muzikant W Artiest (Interface) Werk() Artiest Naam Werk() Muzikant


Download ppt "Richtlijnen Specificaties Multiple inheritence"

Verwante presentaties


Ads door Google