Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

UML og Klasser og Objekter i Python

Lignende præsentationer


Præsentationer af emnet: "UML og Klasser og Objekter i Python"— Præsentationens transcript:

1 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,

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 -attrNummer1 -attrNummer2 +metodeNr1 +metodeNr2 +metodeNr3 Attributter Access modifiers 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-Administrativt Personale VIP=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 def udnaevn(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 def verbalize(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): self.fakulteter = fakulteter class Fakultet(Organisation): def __init__(self, navn,addresse, ledelse, fagområde,institutter,uddannelser): 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 linjers kode

22 Kobling Coupling Skal være lav.
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 Skal være høj.
Sammenhæng indenfor det enkelte modul Logical cohesion: 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) Rekursiv definition Samling ::= {Del}* Del ::= Simpel |Samling Samling Del Del Samling Del Del

29 Nedarvning Subklassen arver variable og funktioner fra superklassen
Simpel: navn __str__ Samling: dele 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 + ')' return text class Samling(Del): def __init__(self, navn, dele = None): Del.__init__(self, navn) if dele == None: self.dele = [] else: self.dele = dele def tilfoej(self,enDel): self.dele.append(enDel) def fjern(self,enDel): if enDel in self.dele: self.dele.remove(enDel) def hent(self,delNavn): for d in self.dele: if d.navn == delNavn: return d return None text = '\n' + niveau *' '+'(' + self.navn for enDel in self.dele: text += enDel.__str__(niveau+1) text += '\n' + niveau *' '+')' class Simpel(Del): 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('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)
(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 def tilfoej(self, enDel): if self.dele == None: self.dele = [] self.dele.append(enDel) def fjern(self,enDel): if enDel in self.dele: self.dele.remove(enDel) def hent(self,delNavn): for d in self.dele: if d.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 *' '+')' return text klassenavn Init metoden (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): Tag (Simpel): 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): {'navn': 'Tag'} '__str__', 'introspect', 'navn'] Nedarvede fra Python Brugerdefinerede

37 Generering af klasser Klasse definition Generering af klasse
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’s init kalder superklassens init Husk at give den parametren self 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__.Simpel instance>, <__main__.Samling instance >, <__main__.Simpel instance >] >>> bil.stelnummer Traceback (most recent call last): File "<pyshell#7>", line 1, in ? bil.stelnummer AttributeError: Samling instance has no attribute '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 def udskrivSum(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:’ 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.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 class Persistent(SQL): '''Abstract class'''
Omdefinering af overklassens funktion Reference til ’mig selv’ class Persistent(SQL): '''Abstract class''' def __init__(self, tableName, values): self.primaryKey = database.getPrimaryKey(tableName) self.tableName = tableName columnNames = database.getColumnNames(tableName) SQL.__init__(self, columnNames, values) def printContents(self): '''prints the data of the object''' print 'Table name: '+self.tableName print 'Primary key: ' + self.primaryKey SQL.printContents(self) def getPrimaryKey(self): '''returns the primary key''' return self.primaryKey Overklassens navn Genbrug af overklassens funktioner

49 Table Self.getPrimaryKey() er nedarvet fra overklassen
class Table(Persistent): def __init__(self, tableName): values = database.findRecords(tableName,[]) Persistent.__init__(self,tableName, values) #insert a list of Row-instances corresponding 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 def getRow(self,theKey): '''returns a row-instance whose primary key = theKey if none exists, returns None''' for r in self.rows: if r.get(primaryKey) == theKey: return r return None def printContents(self): '''prints the data of the object''' print 'Table name: '+self.tableName print 'Primary key: '+ 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 , change the first name to Jeppe and store it, fetch the row again to see if the change worked aRow = Row('Child',' ') aRow.put('firstname','Jeppe') aRow.update() aRow.printContents() Resultat: Table name: Child Primary key: cpr Column names: ['cpr', 'firstname', 'lastname', 'address', 'city', 'gender', ' ', 'phone', 'insurance', 'hasFather', 'hasMother', 'hasDoctor'] Values: [[' ', 'Jeppe', 'Andersen', 'Thorsgade 20', '8410', 'dreng', '', ' ', 'Baltica', ' ', ' ', ' ']]

51 Brug af OOogSQL 2 restore the first name, print a html version of the row aRow.put('firstname','Jeppe Boegh') aRow.update() print aRow.makeHTMLTable()

52 Resultat <table width="75%" border="1"> <tr>
<td>cpr</td> <td>firstname</td> <td>lastname</td> <td>address</td> <td>city</td> <td>gender</td> <td> </td> <td>phone</td> <td>insurance</td> <td>hasFather</td> <td>hasMother</td> <td>hasDoctor</td> </tr> <td> </td> <td>Jeppe Boegh</td> <td>Andersen</td> <td>Thorsgade 20</td> <td>8410</td> <td>dreng</td> <td></td> <td> </td> <td>Baltica</td> <td> </td> <td> </td> <td> </td> </table>

53 Brug af OOogSQL 3 make a new empty row-object, insert values into the object aRow = Row('Child') valueList = [' ', 'Jeppe Boegh', 'Andersen', 'Thorsgade 20', '8410', 'dreng', '', ' ', 'Baltica', ' ', ' ', ' '] aRow.putAllValues(valueList) aRow.printContents() Resultat Table name: Child Primary key: cpr Column names: ['cpr', 'firstname', 'lastname', 'address', 'city', 'gender', ' ', 'phone', 'insurance', 'hasFather', 'hasMother', 'hasDoctor'] Values: [' ', 'Jeppe Boegh', 'Andersen', 'Thorsgade 20', '8410', 'dreng', '', ' ', 'Baltica', ' ', ' ', ' ']

54 Brug af OOogSQL 4 create a selection of all children that live at the same address as their mother' SQLordre = '''SELECT Child.cpr, Child.firstname, Child.lastname FROM Child, Person WHERE Child.hasMother = Person.cpr AND Child.address = Person.address''' aSelection = Temporary(['cpr','firstname','lastname'],SQLordre) aSelection.printContents() Resultat Column names: ['cpr', 'firstname', 'lastname'] Values: ((' ', 'Stine', 'Jacobsen '),)

55 Brug af OOogSQL 5 print aSelection.makeHTMLTable() Resultat
<table width="75%" border="1"> <tr> <td>cpr</td> <td>firstname</td> <td>lastname</td> </tr> <td> </td> <td>Stine</td> <td>Jacobsen </td> </table>

56 Fordelen ved UML Vi kan beskrive de logiske forhold i problemområdet uden at skulle tage beslutninger om implementeringen At kunne dette er jeres hovedkvalifikation. Har vi et godt UML diagram er der ikke lang vej til implementering for dygtige programmører.

57 Databse.py Ny udgave på nettet, har foretaget nogle ændringer, idet at en session førhen blev lukket efter hvert kald. Dette gav problemer med nogle ting Husk at lukke connection nu! database.closeConnection() Eller noget der nedarver SQL klassen, ligeledes objekt.closeConnection()

58 Opgave 9 Øvelse 9 ligger på hjemmesiden.
Udfyld de steder hvor der står ”insert code here” så det passer til beskrivelsen af metoden eller funktionen Test at alting virker som det skal


Download ppt "UML og Klasser og Objekter i Python"

Lignende præsentationer


Annoncer fra Google