1 / 38

H9: Klasse Ontwerp

H9: Klasse Ontwerp. Richtlijnen Specificaties Multiple inheritence. SchetsPlus... doe ik het goed ?. Hoe maak ik goede klassen ?. We gaan kijken naar: algemene ontwerp-richtlijnen software metric

uriah-hood
Download Presentation

H9: Klasse Ontwerp

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 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 GuideAmbler, the Elements of Java Style

  4. Richtlijnen • Structuur is belangrijk, wat je niet wil: • complex  fouten, onderhoudkost • star • Optimaliseer : • encapsulatie • inheritence • cohesie • koppeling

  5. Cohesie • Een “module” is cohesiefals 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 • Pathologischin C++ heb je ook friends. Mixer if (drank.zoet() > 10) { drank.water++ ; drank.roer() ; } Drank - suiker : int - water : int + zoet() : int + roer()

  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, 1987“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!

  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.

  14. Halstead • Complexiteit: moeite om code te lezen E = D * V x = x + x ; x++ x = x + y ; z++ (alleen ter info)

  15. McCabe • Het aantal lineair onafhankelijke paden in je programma. int P() { if (...) return 100 else return 0 } 0 1 2 Control Flow Graph (CFG)

  16. McCabe 0 4 1 3 2 5

  17. Oviedo • Splits programma in sequentiële blokken • 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 } (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

  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.

  20. Koppeling (Cp) • Idee • 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

  23. JHawk

  24. Klasse specificatie Videotheek • 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. . Minderjarig bonus Klant Naam Leeftijd DVD titel leeftijdgrens leent * <is verantwoordelijk voor

  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+ DVD Kill Bill 12+

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

  28. Navigatie in OCL 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 Klant 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. contextx : Klant inv: x.dvds  select (dvd | dvd.premium = true)  size() ≤ 1

  32. Methode specificeren 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=x.dvds@pre insert(d)

  34. Multiple inheritence • 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 … Product ID Naam Prijs GroteBestelling koopGroot(n) ImportGoed invoerBelasting() Koffie

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

  36. Diamantprobleem Persoon Naam Leeftijd • 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… Werknemer Artiest Muzikant

  37. Inheritence vs associatie W Artiest Naam Werk() Artiest Naam Werk() Muzikant Muzikant

  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

More Related