1 / 58

UML og Klasser og Objekter i Python

UML og Klasser og Objekter i Python. Uge 47 Computer science, kap 7 Martin Fowler: UML distilled , kap. 3. Addision-Wesley , 2004. Learning Python : kap 15-16, 19-22. . Diagrammer. Diagrammer er visuelle fremstillinger af beskrivelser der består af en lang række simple ens sætninger.

gwyn
Download Presentation

UML og Klasser og Objekter i Python

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. UML og Klasser og Objekter i Python Uge 47 Computer science, kap 7 Martin Fowler: UML distilled, kap. 3. Addision-Wesley, 2004. LearningPython: kap 15-16, 19-22.

  2. Diagrammer • Diagrammer er visuelle fremstillinger af beskrivelser der består af en lang række simple ens sætninger

  3. Entity-relation • Entitet har Egenskab • Entitet A står-i-relation-til Entitet B Relation Entitet Egenskab

  4. ER-diagram • Et kæledyr har et navn • Et kæledyr har en fødselsdag • Et kæledyr er ejet af en person

  5. Kald-struktur • Structure chart • Funktion A kalder funktion B A B

  6. HTML-tabellen • def makeHtmlPage(tablecontents): • return makeStart() + makeTable(tablecontents) + makeEnding() • def makeTable(tablecontents): • …. • htmltabel += makeRow(row) • … • return htmltabel • def makeRow(rowcontents): • …. • htmlrow += makeCell(cell) • …. • return htmlrow

  7. HTML-tabellen makeHtmlPage(tablecontents): makeEnding() makeStart() makeTable(tablecontents) makeRow(rowcontents): makeCell(cell)

  8. Brugsscenarier • Use case diagrams • Defineret ved formål • Aktør interagerer med Systemmodul • Formål her: brugerne og udvikleren retter simuleringen så den passer med brugernes teori • Hvem har hvilke ansvarsområder

  9. UML klassediagrammer • Klasse A er en underklasse/overklasse af klasse B • Klasse A er en del af/har delen klasse B • Klasse A står i relation til klasse B • Klasse A afhænger af klasse B • Klasse A har attributten B • Klasse A kan udføre metoden B

  10. Konventioner for notationsform • Klasser starter altid med stort begyndelsesbogstav og efterfølgende ord ligeledes med stort • Attributter og metoder starter med lille begyndelsesbogstav og efterfølgende ord med stort Klassenavn MinKlasse Attributter Access modifiers -attrNummer1-attrNummer2 +metodeNr1+metodeNr2 +metodeNr3 Metoder

  11. Generalisering/specialisering • Klasse A er en underklasse/overklasse af klasse B

  12. Aggregering/dekomponering • Klasse A er en del af/har delen klasse B

  13. Organisationer: Århus Universitet TAP=Teknisk-AdministrativtPersonaleVIP=Videnskabeligt Personale

  14. Metoder og attributter • Klasse A kan udføre metoden B • Klassen A har attributten B • Primitive attributter defineres i klassen, komplekse bliver defineret som en ny klasse med et tilhørsforhold class Ledelse: def __init__(self, medlemmer, organisation): self.medlemmer = medlemmer self.organisation = organisation def udnaevn(self, medlem): self.medlemmer.append(medlem) def fjern(self, medlem): self.medlemmer.remove(medlem)

  15. Delvis implementering • class Institut(Organisation): • def __init__(self, navn,addresse, ledelse,fagområde): • Organisation.__init__(self, navn,addresse, ledelse) • self.fagområde = fagområde • class Ledelse: • def __init__(self, medlemmer, organisation): • self.medlemmer = medlemmer • self.organisation = organisation • defudnaevn(self, medlem): • self.medlemmer.append(medlem) • def fjern(self, medlem): • self.medlemmer.remove(medlem) • class Ansat(Entitet): • def __init__(self, navn,addresse, lønramme,cpr,bankkonto): • Entitet.__init__(self,navn, addresse) • self.lønramme = lønramme • self.cpr = cpr • self.bankkonto = bankkonto • class Entitet: • def __init__(self, navn,addresse): • self.navn = navn • self.addresse = addresse • defverbalize(self): • print vars(self) • class Organisation(Entitet): • def __init__(self, navn,addresse, ledelse): • Entitet.__init__(self,navn, addresse) • self.ledelse = ledelse • class Uddannelse(Organisation): • def __init__(self, navn,addresse, ledelse, tilknytning): • Organisation.__init__(self, navn,addresse, ledelse) • self.tilknytning=tilknytning • class Universitet(Organisation): • def __init__(self, navn,addresse, ledelse, fakulteter): • Organisation.__init__(self, navn,addresse, ledelse) • self.fakulteter = fakulteter • class Fakultet(Organisation): • def __init__(self, navn,addresse, ledelse, fagområde,institutter,uddannelser): • Organisation.__init__(self, navn,addresse, ledelse) • self.fagområde = fagområde • self.institutter = institutter • self.uddannelser = uddannelser

  16. Implementering • Aggregering: en liste af komponenterne (en beholder) • Specialisering:subklasser • Attributter: variable knyttet til klassen • Metoder: funktioner knyttet til klassen

  17. Patterns • En gennemtestet metode til at løse et bestemt problem (GOF) • State pattern • Løser problemet at en instans ikke kan skifte klasse • Når man bliver lektor skal man oprette en helt ny ansat

  18. Løs opgave Diagrammet efter diskussion

  19. Software: OOogSql

  20. Software: Beggars and philanthropists Modellering af et simpelt kommunikationssystem for autonome agenter til brug i simuleringer af, hvordan forskellige økonomiske instanser fordeler penge ud fra de ansøgninger de modtager, og ligeledes hvordan de forskellige ansøgere udvælger hvor de skal ansøge.

  21. Beggars and philanthropists demo • Prompten viser hvordan de enkelte agenter kommunikerer med hinanden • Hele kildekoden kan ses bagefter hvis der er nogen der har interesse, består af ca. 2600 linjers kode

  22. Kobling • Coupling • Afhængigheder mellem moduler • Kan man rette i eet modul uden at skulle rette i andre moduler? • Skal være lav. • Skal helst kun være i nedadgående retning • Øger genbrugelighed GUI Model Persistens

  23. Sammenhæng • Cohesion • Sammenhæng indenfor det enkelte modul • Logicalcohesion: en klasse repræsenterer en sammenhængende verden. • En person klasse kan ikke have funktioner til at køre en bil. • Skal være høj. • Øger også genbrugelighed, vi kan bruge en rigtigt defineret person klasse mange gang

  24. Engineering og reverse-engineering • Fra diagrammer til kode, kan automatiseres • Fra kode til diagram kan også automatiseres • Diagrammet fra B&P var reverse-engineered

  25. Pause • Pause

  26. Klasser og objekter

  27. Klasser og objekter • En klasse beskriver en klump af samhørende funktioner og variable • En klasse er en beskrivelse. • En kage form • Klassens objekter er instanser af klassen. • De enkelte kager • En programudførelse indeholder (for det meste (klasse reference)) objekter, ikke klasser

  28. Samlingsmønstret (composite) • Behandl helheder og dele på samme måde (her print) • Rekursivdefinition • Samling ::= {Del}* • Del ::= Simpel |Samling Samling Del Del Samling Del Del

  29. Nedarvning • Subklassen arver variable og funktioner fra superklassen • Simpel: • navn • __str__ • Samling: • navn • dele • __str__ • tilføj • fjern • hent Begge arver navn fra overklassen Simpel bevarer superklassens __str__’ Samling tilføjer nye ting Samling overskriver superklassens ’ __str__’

  30. __init__ og andre funktioner • class Del: • def __init__(self, navn): • self.navn = navn • def __str__(self, niveau = 1): • text = '\n' + niveau *' '+'(' + self.navn + ')' • returntext • class Samling(Del): • def __init__(self, navn, dele = None): • Del.__init__(self, navn) if dele == None: self.dele = [] else: • self.dele= dele • deftilfoej(self,enDel): • self.dele.append(enDel) • def fjern(self,enDel): • ifenDel in self.dele: • self.dele.remove(enDel) • def hent(self,delNavn): • for d in self.dele: • ifd.navn == delNavn: • return d • return None • def __str__(self, niveau = 1): • text = '\n' + niveau *' '+'(' + self.navn • for enDel in self.dele: • text += enDel.__str__(niveau+1) • text += '\n' + niveau *' '+')' • returntext • class Simpel(Del): • def __init__(self, navn): • Del.__init__(self, navn) superklasse initialisering subklasse metoder subklasse

  31. Dannelse af objekter Inits parametre • bil = Samling('bil',[Samling('karosseri'),Samling('hjul'),Samling('motor')]) • bil.hent('karosseri').tilfoej(Simpel('Tag')) • bil.hent('karosseri').tilfoej(Simpel('Doere')) • bil.hent('karosseri').tilfoej(Simpel('Bund')) • bil.hent('hjul').tilfoej(Simpel('venstre forhjul')) • bil.hent('hjul').tilfoej(Simpel('venstre forhjul')) • bil.hent('hjul').tilfoej(Simpel('hoejre forhjul')) • bil.hent('hjul').tilfoej(Simpel('venstre baghjul')) • bil.hent('hjul').tilfoej(Simpel('hoejre baghjul')) • bil.hent('motor').tilfoej(Simpel('stempler')) • bil.hent('motor').tilfoej(Simpel('karburator')) • print bil Kald af hjulsamlingens tiltøj-funktion

  32. Output • (bil • (karosseri • (Tag) • (Doere) • (Bund) • ) • (hjul • (venstre forhjul) • (venstre forhjul) • (hoejre forhjul) • (venstre baghjul) • (hoejre baghjul) • ) • (motor • (stempler) • (karburator) • ) • )

  33. Definition af klasser: superklasse • Class <klassenavn>(<evt. superklasse>): • <init-funktionen> • <funktioner der tilhører klassen> • class Samling(Del): • '''repræsenterer en samling af dele, enten samlinger eller simple''' • def __init__(self, navn, dele = None): • Del.__init__(self, navn) • self.dele = dele • deftilfoej(self, enDel): • ifself.dele == None: • self.dele = [] • self.dele.append(enDel) • def fjern(self,enDel): • ifself.dele == None: • self.dele = [] • ifenDel in self.dele: • self.dele.remove(enDel) • def hent(self,delNavn): • for d in self.dele: • ifd.navn == delNavn: • return d • return None • def __str__(self, niveau = 1): • '''giver en textuel repræsentation af klassen • __str__ gør det muligt at printe klassen direkte''' • text = '\n' + niveau *' '+'(' + self.navn • for enDel in self.dele: • text += enDel.__str__(niveau+1) • text += '\n' + niveau *' '+')' • returntext klassenavn Initmetoden (Constructor) metoder der tilhører klassen

  34. Check om det er rigtigt: Introspektion • Python indeholder en række funktioner der giver direkte adgang til dens indvolde • Objekt.__dict__: en dictionary der gemmer objektets attributter og værdier • Dir(object): returnerer alle de attributter og metoder der er knyttet til objektet.

  35. Introspection • def introspect(self): • text = 'Dictionary: ' • text += '\n'+ str(self.__dict__) • text += '\n'+'Attributes and functions: ' • text += '\n'+ str(dir(self)) • return text

  36. Eksempel • Bil (Samling): • Dictionary: • {'dele': [<__main__.Samling instance at 0x00FC2BE8>, <__main__.Samling instance at 0x00FC2CD8>, <__main__.Samling instance at 0x00FC2D00>], • 'navn': 'bil'} • Attributes and Functions : • ['__doc__', '__init__', '__module__', • '__str__', 'dele', 'fjern', 'hent', 'introspect', 'navn', 'tilfoej'] • Tag (Simpel): • Dictionary: • {'navn': 'Tag'} • Attributes and Functions : • ['__doc__', '__init__', '__module__', • '__str__', 'introspect', 'navn'] Nedarvede fra Python Brugerdefinerede

  37. Generering af klasser • Klasse definition • class Simpel(Del): • def __init__(self, navn): • Del.__init__(self, navn) • Generering af klasse • <klassenavn>(<inits parametre undtagen self>) • Forhjul = Simpel('venstre forhjul') • __init__kaldes automatisk når klassen genereres Simpel’sinit kalder superklassens init Husk at give den parametrenself med!!

  38. Self • self henviser til det nydannede objekt • Når man i klassedefinitionen vil henvise til objektets egne funktioner eller variable skal det ske via self • def getName(self): • return self.name

  39. Med og uden self • class Samling(Del): • def __init__(self, navn, dele): • Del.__init__(self, navn) • self.dele = dele • stelnummer = 100 • ’Stelnummer’ er blot en lokal variabel i __init__ der forsvinder når funktionen har kørt. ’Dele’ er derimod fast knyttet til objektet • >>> bil.dele • [<__main__.Simpelinstance>, <__main__.Samlinginstance >, <__main__.Simpelinstance >] • >>> bil.stelnummer • Traceback (most recent call last): • File "<pyshell#7>", line 1, in ? • bil.stelnummer • AttributeError: Samling instance has noattribute 'stelnummer' • >>>

  40. Self bruges også til at referere til objektets egne funktioner • class Eksempel: • def __init__(self,enListe): • self.minListe = enListe • def summer(self): • resultat = 0 • for i in self.minListe: • resultat += i • return resultat • defudskrivSum(self): • print self.summer() • etElement = Eksempel([1,2,3,4]) • etElement.udskrivSum() • Resultat: • 10 • >>>

  41. Udeladelse af self • def udskrivSum(self): • print summer() • Python ved ikke hvad ’summer’ refererer til:’ • print summer() • NameError: global name 'summer' is not defined

  42. Klasse variabler • Det er også muligt at referere direkte til parametre defineret i klassen i stedet for objektet. Dette gøres uden self • Brug af konstante til at gøre koden renere og lettere at omstrukturere, vi bruger A.meters alle steder i stedet for tallet 100, hvis det skulle ændre sig skal vi kun ændre et sted Er defineret uden for klassens metoder!Derfor ydre scope class A: meters = 100 def printer(self): self.meters = 50 print "i objektet: " + str(self.meters)+", i klassen: "+str(A.meters) print "i klassen: "+ str(A.meters) instance = A() instance.printer() >>> >>>i klassen: 100 >>>i objektet: 50, i klassen: 100 >>>

  43. Hele Python består af objekter • >>> L = [1,2,3] • >>> L.append(4) • >>> L • [1, 2, 3, 4] • >>>

  44. Relationer mellem objekter • Der er en én-mange relation mellem en samling og dens dele • En relation er et abstrakt begreb der kan implementeres på mange måder. • SQL: som en relation • Python: som en liste af objekter

  45. SQL • Helhedens primærnøgle benyttes som fremmednøgle i delen Del Samling

  46. Python • class Samling(Del): • def __init__(self, navn, dele): • Del.__init__(self, navn) • self.dele = dele • Helheden har en liste over de objekter der repræsenterer dens dele

  47. OOogSQL

  48. Persistent Omdefinering af overklassens funktion Reference til ’mig selv’ • classPersistent(SQL): • '''Abstractclass''' • def __init__(self, tableName, values): • self.primaryKey = database.getPrimaryKey(tableName) • self.tableName = tableName • columnNames = database.getColumnNames(tableName) • SQL.__init__(self, columnNames, values) • defprintContents(self): • '''prints the data of the object''' • print 'Tablename: '+self.tableName • print 'Primarykey: ' + self.primaryKey • SQL.printContents(self) • defgetPrimaryKey(self): • '''returns the primarykey''' • returnself.primaryKey Overklassens navn Genbrug afoverklassensfunktioner

  49. Table • classTable(Persistent): • def __init__(self, tableName): • values = database.findRecords(tableName,[]) • Persistent.__init__(self,tableName, values) • #insert a list of Row-instancescorresponding to the values • rows =[] • primaryKey = self.getPrimaryKey() • i = self.columnNames.index(primaryKey) • for v in self.values: • theKey = v[i] • rows.append(Row(tableName,theKey)) • self.rows = rows • defgetRow(self,theKey): • '''returns a row-instancewhoseprimarykey = theKey • if none exists, returns None''' • primaryKey = self.getPrimaryKey() • for r in self.rows: • ifr.get(primaryKey) == theKey: • return r • return None • defprintContents(self): • '''prints the data of the object''' • print 'Tablename: '+self.tableName • print 'Primarykey: '+ self.primaryKey • print ’Column names: \n' + str(self.columnNames) • print 'Components: ' • for c in self.rows: • c.printContents() Self.getPrimaryKey() er nedarvet fra overklassen

  50. Brug af OOogSQL 1 • fetch a row from Child with primary key 1111111111, change the first name to Jeppe and store it, fetch the row again to see if the change worked • aRow = Row('Child','1111111111') • aRow.put('firstname','Jeppe') • aRow.update() • aRow = Row('Child','1111111111') • aRow.printContents() • Resultat: • Table name: Child • Primary key: cpr • Column names: ['cpr', 'firstname', 'lastname', 'address', 'city', 'gender', 'email', 'phone', 'insurance', 'hasFather', 'hasMother', 'hasDoctor'] • Values: [['1111111111', 'Jeppe', 'Andersen', 'Thorsgade 20', '8410', 'dreng', '', '86379790', 'Baltica', '1111111112', '1111111113', '1111111114']]

More Related