Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Konzepte objektorientierter Programmierung: Beziehungen zwischen Objekten Klaus Becker 2016.

Ähnliche Präsentationen


Präsentation zum Thema: "Konzepte objektorientierter Programmierung: Beziehungen zwischen Objekten Klaus Becker 2016."—  Präsentation transkript:

1 Konzepte objektorientierter Programmierung: Beziehungen zwischen Objekten
Klaus Becker 2016

2 Spiele am Computer "Objektorientierung ist die derzeitige Antwort auf die gestiegene Komplexität der Softwareentwicklung." Oestereich: Objektorientierte Software-Entwicklung Wir werden hier einfache Spielprogramme mit Hilfe von Softwarebausteinen entwickeln. Dabei sollen die Grundideen und Fachkonzepte der objektorientierten Programmierung im Vordergrund stehen und Schritt für Schritt entwickelt werden.

3 Verwaltung von Objekten
Teil 1 Verwaltung von Objekten

4 Würfelspiele Ziel ist es, Würfelspiele mit Hilfe von Objekten zu simulieren. Dabei steht hier das Zusammenspiel der Objekte im Vordergrund. Zunächst betrachten wir die Verwaltung von Objekten.

5 Würfelobjekte erzeugen und verwalten
>>> >>> w1 = Wuerfel() >>> w2 = w1 >>> w3 = w1 >>> w1.werfen() >>> w1.getAugen() 6 >>> w2.getAugen() >>> w3.getAugen() >>> w2.werfen() 4 >>> >>> w1 = Wuerfel() >>> w2 = Wuerfel() >>> w3 = Wuerfel() >>> w1.werfen() >>> w1.getAugen() 4 >>> w2.getAugen() 2 >>> w3.getAugen() 1 >>> w2.werfen() 6 Aufgabe: Schaue dir die beiden folgenden Python-Dialoge genau an (und führe sie selber durch). Worin unterscheiden sie sich? Kannst du das unterschiedliche Verhalten auch erklären?

6 Würfelobjekte erzeugen und verwalten
Aufgabe: Führe die entsprechenden Python-Programme auch mit dem Python-Tutor aus (siehe

7 Würfelobjekte erzeugen und verwalten
Aufgabe: Führe die entsprechenden Python-Programme auch mit dem Python-Tutor aus (siehe

8 Objekte und ihre Identität
>>> w1 = Wuerfel() >>> w1 <__main__.Wuerfel object at 0x0135DDB0> >>> id(w1) >>> hex( ) '0x135ddb0' >>> w1 = Wuerfel() >>> w2 = w1 >>> id(w1) >>> id(w2) >>> w1 = Wuerfel() >>> w2 = Wuerfel() >>> id(w1) >>> id(w2) Aufgabe: (a) Mit dem id-Operator kann man sich die sogenannte Identitätsnummer eines Objekts anzeigen lassen. Was verbirgt sich wohl hinter dieser Identitätsnummer? (b) Was zeigen die beiden Python-Dialoge? Kannst du jetzt die Ergebnisse der oben gezeigten Python-Dialoge erklären?

9 Identität von Objekten
(Daten-) Objekte haben - analog zu Objekten unserer Lebenswelt - ebenfalls eine Identität. Zur eindeutigen Identifizierung werden sie mit Identitätsnummern versehen. Verschiedene Objekte unterscheiden sich in ihrer Identitätsnummer. Sie können aber durchaus denselben Objektzustand haben. Ein Objekt behält während seiner Lebensdauer immer die einmal vergebene Identitätsnummer. Auch wenn sich der Zustand des Objekts verändert, so bleibt doch die Identitätsnummer des Objekts bestehen. Häufig verwendet hierzu man eine Adresse im Speicher des Rechners als Identitätsnummer. Die Identitätsnummer eines Objekts zeigt dann auf den Speicherbereich, in dem die Daten des Objekts abgelegt sind. Diese Identifikation von Objekten durch eine Lokalisierung im Speicher setzt natürlich voraus, dass Objekte im Speicher nicht hin und her wandern, sondern dass der einmal zugeteilte Speicherbereich während der Lebensdauer eines Objekts bestehen bleibt. Wir gehen im Folgenden von dieser Vorstellung aus. >>> w1 = Wuerfel() >>> w1 <__main__.Wuerfel object at 0x0135DDB0> >>> id(w1) >>> hex( ) '0x135ddb0'

10 Zeiger / Referenzen Eine Variable ist ein Name, der (in der Regel) mit einem Objekt verknüpft ist. Wenn eine Variable ein (Daten-) Objekt verwaltet, dann verwaltet es die Speicheradresse (bzw. Identitäsnummer) dieses Objekts. Da die Speicheradresse auf das Objekt zeigt bzw. das Objekt referenziert, nennt man eine solche Adresse auch Zeiger bzw. Referenz und die Variable zur Verwaltung der Adresse Zeigervariable bzw. Referenzvariable.

11 Zuweisungen bei Zeigervariablen
w1 = Wuerfel() w2 = w1 w1.werfen() w2 = Wuerfel()

12 Unveränder-bares Objekt
Objekte in Python w1 = Wuerfel() w1 = randint(1,6) w2 = w1 w2 = w1 w1.werfen() w1.randint(1, 6) Veränderbares Objekt Unveränder-bares Objekt Python unterscheidet zwischen veränder-baren und unveränderbaren Objekten.

13 Verbindung von Objekten
Teil 2 Verbindung von Objekten

14 Aktivierung von Würfel
In unserer Lebenswelt werden Würfel aktiviert, indem sie von einer Person geworfen werden. Wir berücksichtigen dies bei der Modellierung einer Würfelsituation. Das Spieler-Objekt soll über zwei Attribute verfügen, um Referenzen auf die beiden Wuerfel-Objekte zu verwalten.

15 Spieler-Objekt - Version 1
class Wuerfel(object): class Spieler(object): def __init__(self): self.rWuerfel1 = None self.rWuerfel2 = None # Test w1 = Wuerfel() # 1 w2 = Wuerfel() # 2 print(w1.getAugen(), w2.getAugen()) sp1 = Spieler() # 3 sp1.rWuerfel1 = w # 4 sp1.rWuerfel2 = w # 5 sp1.rWuerfel1.werfen() # 6 sp1.rWuerfel2.werfen() # 7 Aufgabe: Die Anweisungen im Testprogramm sind durchnummeriert. Welche dieser Anweisungen werden benutzt, um die im Objektdiagramm gezeigte Objektkonstellation zu erzeugen? Gib hierzu genau an, wie die Objektkonstellation Schritt für Schritt erzeugt wird.

16 Spieler-Objekt - Version 2
class Wuerfel(object): class Spieler(object): def __init__(self): self.rWuerfel1 = None self.rWuerfel2 = None def spielen(self): self.rWuerfel1.werfen() self.rWuerfel2.werfen() # Test w1 = Wuerfel() # 1 w2 = Wuerfel() # 2 print(w1.getAugen(), w2.getAugen()) sp1 = Spieler() # 3 sp1.rWuerfel1 = w # 4 sp1.rWuerfel2 = w # 5 sp1.spielen() # 6 Aufgabe: In der folgenden Implementierung ist in der Klasse Spieler eine Methode spielen() ergänzt. Erkläre, was die Anweisung sp1.spielen() leistet.

17 Spieler-Objekt - Version 3
class Wuerfel(object): class Spieler(object): def __init__(self, pWuerfel1, pWuerfel2): self.rWuerfel1 = pWuerfel1 self.rWuerfel2 = pWuerfel2 def spielen(self): self.rWuerfel1.werfen() self.rWuerfel2.werfen() # Test w1 = Wuerfel() # 1 w2 = Wuerfel() # 2 print(w1.getAugen(), w2.getAugen()) sp1 = Spieler(w1, w2) # 3 sp1.spielen() # 4 Aufgabe: Erkläre, wie hier die gezeigte Objektkonstellation erzeugt wird. Ergänze einen zweiten Spieler, der ebenfalls die beiden Würfel werfen kann.

18 Spieler-Objekt - Version 3
class Wuerfel(object): class Spieler(object): def __init__(self, pWuerfel1, pWuerfel2): self.rWuerfel1 = pWuerfel1 self.rWuerfel2 = pWuerfel2 self.augensumme = None def spielen(self): self.rWuerfel1.werfen() self.rWuerfel2.werfen() self.augensumme = \ w1.getAugen() + w2.getAugen()) # Test w1 = Wuerfel() # 1 w2 = Wuerfel() # 2 sp1 = Spieler(w1, w2) # 3 sp1.spielen() # 4 Aufgabe: Deute das Sequenzdiagramm.

19 Fachkonzept - Beziehung
Wenn ein Objekt über einen Zeiger (eine Referenz) Zugriff auf ein anderes Objekt hat, so liegt eine (gerichtete) Beziehung zwischen den Objekten vor. Damit das Spieler-Objekt Zugriff auf die Wuerfel-Objekte erhält, wird es mit sogenannten Referenzattributen versehen. Das Spieler-Objekt verfügt über die Attribute rWuerfel1 und rWuerfel2, deren Werte Referenzen bzw. Zeiger auf die entsprechenden Wuerfel-Objekt sind. Objektdiagramm Mit Hilfe eines Aufrufs wie z.B. spieler.rWuerfel1.werfen() kann das Spieler-Objekt sp1 jetzt Methoden der zugeordneten Wuerfel-Objekte aktivieren. Das Spieler-Objekt sp1 hat somit Zugriff auf die Wuerfel-Objekte. Man sagt auch, dass das Spieler-Objekt sp1 in Beziehung zu den Wuerfel-Objekten w1 und w2 steht.

20 Fachkonzept - Beziehung
Wenn ein Objekt über einen Zeiger (eine Referenz) Zugriff auf ein anderes Objekt hat, so liegt eine (gerichtete) Beziehung zwischen den Objekten vor. Um zu verdeutlichen, dass Objekte einer Klasse in Beziehung zu Objekten einer anderen Klasse stehen, wird im Klassendiagramm diese Beziehung durch einen Pfeil verdeutlicht. Die Beziehung kann - wie im Diagramm zu sehen - zusätzlich mit Kardinalitätsangaben genauer beschrieben werden. Objektdiagramm Klassendiagramm

21 Übungen #---------------------------------------- # Wuerfel
from random import randint class Wuerfel(object): # Wuerfelbecher class Wuerfelbecher(object): def __init__(self): self.w1 = None self.w2 = None self.w3 = None def wuerfelHerausrollen(self): self.w1.werfen() self.w2.werfen() self.w3.werfen() Aufgabe 1: Die Anweisungen im Testprogramm sind durchnummeriert. Welche dieser Anweisungen werden benutzt, um die Objekte zu erzeugen und zu verbinden? # Test wuerfel1 = Wuerfel() # 1 wuerfel2 = Wuerfel() # 2 wuerfel3 = Wuerfel() # 3 becher = Wuerfelbecher() # 4 becher.w1 = wuerfel # 5 becher.w2 = wuerfel # 6 becher.w3 = wuerfel # 7 becher.wuerfelHerausrollen() # 8 print(wuerfel1.getAugen()) # 9 print(wuerfel2.getAugen()) # 10 print(wuerfel3.getAugen()) # 11

22 Übungen … class Wuerfelbecher(object): def __init__(self):
self.w1 = None self.w2 = None self.w3 = None def setWuerfel(self, pW1, pW2, pW3): self.w1 = pW1 self.w2 = pW2 self.w3 = pW3 def getWuerfel(self): wListe = [self.w1, self.w2, self.w3] return wListe def wuerfelHerausrollen(self): wuerfel1 = Wuerfel() wuerfel2 = Wuerfel() wuerfel3 = Wuerfel() becher = Wuerfelbecher() becher.setWuerfel(wuerfel1, wuerfel2, wuerfel3) becher.wuerfelHerausrollen() print(wuerfel1.getAugen()) print(wuerfel2.getAugen()) print(wuerfel3.getAugen()) Aufgabe 2: Worin unterscheidet sich die folgende Implementierung zum Würfelsystem von der oben gezeigten Implementierung?

23 Übungen … class Wuerfelbecher(object): def __init__(self):
self.w1 = None self.w2 = None self.w3 = None def setWuerfel(self, pW1, pW2, pW3): self.w1 = pW1 self.w2 = pW2 self.w3 = pW3 def getWuerfel(self): wListe = [self.w1, self.w2, self.w3] return wListe def wuerfelHerausrollen(self): wuerfel1 = Wuerfel() wuerfel2 = Wuerfel() wuerfel3 = Wuerfel() becher = Wuerfelbecher() becher.setWuerfel(wuerfel1, wuerfel2, wuerfel3) becher.wuerfelHerausrollen() for wuerfel in …: print(…) Aufgabe 3: Die Ausgabe der Würfelergebnisse könnte man hier auch anders realisieren. Wie?

24 Übungen #---------------------------------------- # Wuerfel
from random import randint class Wuerfel(object): # Wuerfelbecher class Wuerfelbecher(object): def __init__(self, pW1, pW2, pW3): self.w1 = pW1 self.w2 = pW2 self.w3 = pW3 def wuerfelHerausrollen(self): self.w1.werfen() self.w2.werfen() self.w3.werfen() Aufgabe4: Schaue dir den Kon-struktor der Klasse Wuerfelbecher genau an. Was ist hier anders gemacht? Wie funktioniert die Er-zeugung und Ver-bindung der Objekte? # Test wuerfel1 = Wuerfel() wuerfel2 = Wuerfel() wuerfel3 = Wuerfel() becher = Wuerfelbecher(wuerfel1, wuerfel2, wuerfel3) becher.wuerfelHerausrollen() print(wuerfel1.getAugen()) print(wuerfel2.getAugen()) print(wuerfel3.getAugen())

25 Interaktion von Objekten
Teil 3 Interaktion von Objekten

26 Das Spiel Elf-hoch Das Spiel Elf hoch wird mit zwei Würfeln und zwei oder mehr Personen gespielt. Die Regeln sind auf Wikipedia - Elf hoch beschrieben. Wir werden das Spiel vorerst in der folgenden, etwas vereinfachten Version spielen: Jeder Spieler hat zu Beginn eine bestimmte Anzahl von Spielmarken. Es gibt eine zentral gelagerte Kasse, in der Spielmarken verwaltet werden. In unserer vereinfachten Version muss kein Spieleinsatz gezahlt werden. Die Spieler werfen reihum die beiden Würfel. Ein Spielleiter gibt vor, wer gerade dran ist. Bei einer Augensumme 12 (d.h. zwei Sechsen) muss ein Spieler 12 Marken in die Kasse zahlen. Bei einer Augensumme 11 erhält ein Spieler alle Marken, die sich zu dem Zeitpunkt in die Kasse befinden. Bei allen anderen Augensummen (d.h. weniger als 11) muss ein Spieler so viele Marken in die Kasse zahlen, wie ihm zur Augensumme 11 fehlen.

27 Das Spiel Elf-hoch Folgended Spielsituation soll mit Objekten erfasst werden: Es gibt 2 Würfel, die geworfen werden können. Es gibt eine Kasse, in die Marken eingezahlt und aus der Marken ausgezahlt werden können. Es sollen (vorerst) 3 Spieler mitspielen. Jeder Spieler hat einen Namen und verfügt über eine bestimmte Anzahl von Marken. Jeder Spieler kann die Würfel werfen. Jeder Spieler hat zudem Zugriff auf die Kasse. Es gibt einen Spielmanager, der das Spiel leitet. Der Spielmanager fordert hierzu die Spieler der Reihe nach zum Spielen auf. Welche Objekte sollen zur Simulation des Spiels Elf-hoch benutzt werden? Beschreibe, für welche Aufgaben die Objekte zuständig sind. Beschreibe auch, welche Daten die Objekte verwalten und welche Operationen die Objekte ausführen sollen. Beschreibe zudem, welches Objekt welches andere kennt.

28 Objekte zum Spiel Elf-hoch

29 Das Spiel Elf-hoch als Rollenspiel
Jedes Objekt wird von einer Person gespielt. Jede Person (jedes Objekt) erhält einen Zettel, auf dem sie sich Daten (Attributwerte und Werte von Hilfsvariablen) notieren kann. Jede Person (jedes Objekt) kann nur bestimmte Operationen ausführen. Diese werden im Vorfeld festgelegt und notiert. Eine Person (ein Objekt) kann eine andere Person (ein anderes Objekt) auffordern, eine Operation auszuführen. Hierzu ruft die Person der anderen Person die auszuführende Operation zu. Die ausführende Person kann ggf. eine Antwort zurückrufen. Außer durch Zurufen von Operationen (und Antworten) dürfen die Personen nicht miteinander kommunizieren.

30 Das Spiel Elf-hoch als Rollenspiel
Wie müssen die Objekte agieren, wenn das Spielmanager-Objekt m die Methode spielrundeDurchfuehren ausführt? Ergänze hierzu die folgende informelle Beschreibung. Das Spielmanager-Objekt m fordert das Spieler-Objekt sp1 auf, die Methode spielen auszuführen. Das Spieler-Objekt sp1 führt hierzu folgende Aktionen aus: Es fordert das Wuerfel-Objekt w1 auf, die Methode werfen auszuführen. ...

31 Objekte und ihre Beziehungen
Objektdiagramm

32 Klassen zur Erzeugung der Objekte
Klassendiagramm

33 Objekte in Aktion Sequenzdiagramm

34 Implementierung Aufgabe:
Versuche, möglichst selbstständig das gesamte Elf-hoch-Modell zu implementieren. Wenn du Hilfe benötigst, dann bearbeite die folgenden Teilaufgaben. (a) Die Klassen Wuerfel und Kasse kannst du separat entwickeln und testen. (b) Wenn du Hilfe bei der Entwicklung der Klasse Spieler benötigst, dann benutze die Implementierung in der Datei elfhoch_version0.py als Ausgangspunkt. Analysiere die hier vorgegebene Implementierung. Ergänze die Implementierung der Methode spielen. Orientiere dich am oben gezeigten Sequenzdiagramm. Beachte hierbei, dass im Sequenzdiagramm nur ein spezieller Fall (Augensumme beträgt 12) dargestellt ist. Teste deine Implementierung. (c) Wenn du Hilfe bei der Entwicklung der Klasse Spielmanager benötigst, dann benutze die Implementierung in der Datei elfhoch_version1.py als Ausgangspunkt. Analysiere die hier vorgegebene Implementierung. Ergänze die Implementierung der Methode spielrundeDurchfuehren. Das ist ganz einfach, weil nur die Spieler der Reihe nach aktiviert werden müssen. Teste deine Implementierung.

35 Fachkonzept - Interaktion
Objekte können (in aller Regel) bestimmte Operationen mit den von ihnen verwalteten Daten ausführen. Die Ausführung einer Operationen wird als Dienst anderen Objekten zur Verfügung gestellt. Andere Objekte können den zur Verfügung gestellten Dienst dann nutzen. Hier wird also die Anbieter-Nutzer-Sichtweise benutzt. Wenn ein Objekt den Dienst eines anderen Objekt nutzen will, dann schickt es ihm eine Nachricht. Das Senden einer Nachricht bedeutet, ein Objekt zu veranlassen, eine seiner als Dienste zur Verfügung gestellten Operationen auszuführen. Das Versenden von Nachrichten wird als Interaktion zwischen Objekten gedeutet. Voraussetzung für eine Interaktion zwischen Objekten ist, dass diese miteinander in Beziehung stehen. Eine Pizzeria bietet Pizza ausliefern als Dienst an. Durch eine Nachricht an die Pizzeria kann man diesen Dienst in Anspruch nehmen, d.h. die Pizzeria auffordern, ihren Dienst auszuführen. Ein Kunde muss die Pizzeria kennen, um eine Bestellnachricht an sie senden zu können und mit ihr in der gewünschten Weise interagieren zu können.

36 Fachkonzept - Beziehung
Ein Spieler-Objekt bietet den Dienst spielen() an. Wenn es durch eine Nachricht (von einem Spielmanager-Objekt) aufgefordert wird, diesen Dienst auszuführen, dann schickt es seinerseits Nachrichten an Objekte, um diese zur Mitarbeit aufzufordern. Zuächst schickt das Spieler-Objekt Nachrichten an die beiden Wuerfel-Objekte, um deren Dienst werfen() zu nutzen. Anschließend schickt das Spieler-Objekt noch einmal Nachrichten an die beiden Wuerfel-Objekte, um sich die Würfelergebnisse zu besorgen. Wenn die Summe der Würfelergebnisse 12 beträgt, schickt das Spieler-Objekt schließlich eine Nachricht an das Kasse-Objekte, um dessen Dienst einzahlen(...) in Anspruch zu nehmen. Ähnlich agiert das Spieler-Objekt, wenn eine andere Summe der Würfelergebnisse vorliegt. Das Spieler-Objekt interagiert also hier mit den Wuerfel-Objekten und dem Kasse-Objekt. Dies alles ist deshalb möglich, weil das Spieler-Objekt in Beziehung zu den betreffenden Objekten steht und diese die passenden Dienste anbieten.

37 Kennt-Beziehung / Hat-Beziehung
Teil 4 Kennt-Beziehung / Hat-Beziehung

38 Das Spiel Elf-hoch Wir betrachten weiterhin das Spiel Elf-hoch. Hier soll es jetzt um die Verwaltung der Spielmarken gehen. Jeder Spieler hat zu Beginn eine bestimmte Anzahl von Spielmarken. Es gibt eine zentral gelagerte Kasse, in der Spielmarken verwaltet werden. In unserer vereinfachten Version muss kein Spieleinsatz gezahlt werden. Die Spieler werfen reihum die beiden Würfel. Bei einer Augensumme 12 (d.h. zwei Sechsen) muss ein Spieler 12 Marken in die Kasse zahlen. Bei einer Augensumme 11 erhält ein Spieler alle Marken, die sich zu dem Zeitpunkt in die Kasse befinden. Bei allen anderen Augensummen (d.h. weniger als 11) muss ein Spieler so viele Marken in die Kasse zahlen, wie ihm zur Augensumme 11 fehlen.

39 Verwaltung der Spielmarken
Bisher haben wir die Anzahl der Spielmarken eines Spielers mit einem entsprechenden Attribut verwaltet. Die Spielmarken, die in die Kasse eingezahlt werden, haben wir dagegen mit einem eigenen Objekt verwaltet.

40 Verwaltung der Spielmarken
Die Spielmarken der Spieler sollen jetzt ebenfalls mit passenden Objekten verwaltet werden. Es bietet sich an, hier auch Objekte der Klasse Kasse zu benutzen.

41 Erzeugung der Kasse-Objekte
Bei der Erzeugung dieses zusätzlichen Kasse-Objekts gehen wir einen anderen Weg. Dieses zusätzlichen Kasse-Objekt soll vom Spieler-Objekt erzeugt (und vernichtet) werden. Beachte, dass das Spieler-Objekt jetzt Referenzen aud zwei Kasse-Objekte hat.

42 Erzeugung der Kasse-Objekte
class Spieler(object): def __init__(self, pName, pMarken, pWuerfel1, pWuerfel2, pSpielKasse): self.name = pName self.rMeineKasse = Kasse(pMarken) self.rWuerfel1 = pWuerfel1 self.rWuerfel2 = pWuerfel2 self.rSpielKasse = pSpielKasse w1 = Wuerfel() w2 = Wuerfel() k = Kasse(0) sp1 = Spieler('Winner', 100, w1, w2, k) sp2 = Spieler('Looser', 100, w1, w2, k) sp3 = Spieler('Zitterhand', 100, w1, w2, k) m = Spielmanager(sp1, sp2, sp3) Aufgabe: Warum ist des Spieler-Objekt für die Erzeugung des neuen Kasse-Objekts zuständig? An welcher Stelle im Quelltext zeigt sich das? Wie muss der Markenaustausch beim Spielen jetzt ralisiert werden?

43 Fachkonzept – Kennt-/Hat-Beziehung
Man unterscheidet zwischen einer Kennt-Beziehung, bei der die beteiligten Objekte ein Eigenleben führen, und einer Hat-Beziehung, bei der ein Objekt auch für die Erzeugung (und Vernichtung) des in Beziehung stehenden Objekts zuständig ist. Die hier benutzten Kasse-Objekte unterscheiden sich in einem zentralen Punkt. Das Kasse-Objekt k für die Verwaltung der Spielkasse führt eine Art "Eigenleben". Es existiert unabhängig von allen anderen Objekten. Das Kasse-Objekt für die Verwaltung der Spielmarken eines Spielers ist hingegen abhängig vom betreffenden Spieler-Objekt. Das Spieler-Objekt ist für die Erzeugung des Kasse-Objekts zuständig. Das Kasse-Objekt existiert auch nur solange, wie es das Spieler-Objekt gibt. Beachte, dass die unterschiedlichen Beziehungen im Objektdiagramm nur schwer zu erkennen sind.

44 Fachkonzept – Kennt-/Hat-Beziehung
Man unterscheidet zwischen einer Kennt-Beziehung, bei der die beteiligten Objekte ein Eigenleben führen, und einer Hat-Beziehung, bei der ein Objekt auch für die Erzeugung (und Vernichtung) des in Beziehung stehenden Objekts zuständig ist. In Klassendiagrammen benutzt man dagegen unterschiedliche Symbole zur Kennzeichnung der unterschiedlichen Beziehungen.

45 Übungen Aufgabe 1 Wir ändern das Elf-hoch-Spielszenario wie folgt ab: Jeder Spieler bringt seine eigenen Würfel mit. Wie wirkt sich diese Veränderung im Objektdiagramm / Klassendiagramm aus?

46 Übungen Aufgabe 2 Wir ändern das Elf-hoch-Spielszenario wie folgt ab: Jeder Spieler bringt seine eigenen Würfel mit. Was muss an der bisherigen Implementierung des Elf-hoch-Spiels abgeändert werden? class Spieler(object): def __init__(self, pName, pMarken, pWuerfel1, pWuerfel2, pSpielKasse): self.name = pName self.rMeineKasse = Kasse(pMarken) self.rWuerfel1 = pWuerfel1 self.rWuerfel2 = pWuerfel2 self.rSpielKasse = pSpielKasse w1 = Wuerfel() w2 = Wuerfel() k = Kasse(0) sp1 = Spieler('Winner', 100, w1, w2, k) sp2 = Spieler('Looser', 100, w1, w2, k) sp3 = Spieler('Zitterhand', 100, w1, w2, k) m = Spielmanager(sp1, sp2, sp3)

47 Teil 5 Beziehungspartner

48 Das Spiel Elf-hoch Bisher haben wir das Spiel Elf-hoch immer in einer etwas vereinfachten Version gespielt. Wir haben darauf verzichtet, dass zu Beginn des Spiels und nachdem einer der Spieler die Kasse mit einem 11er-Wurf leergeräumt hat jeder Spieler eine Marke in die Kasse zahlen muss. Im Folgenden soll das Spiel nach den normalen Spielregeln duchgeführt werden. Jeder Spieler hat zu Beginn eine bestimmte Anzahl von Spielmarken. Es gibt eine zentral gelagerte Kasse, in der Spielmarken verwaltet werden. Jeder Spieler zahlt zu Beginn eine Marke in die Spielkasse. Die Spieler werfen reihum die beiden Würfel. Bei einer Augensumme 12 (d.h. zwei Sechsen) muss ein Spieler 12 Marken in die Kasse zahlen. Bei einer Augensumme 11 erhält ein Spieler alle Marken, die sich zu dem Zeitpunkt in die Kasse befinden. Jeder Spieler zahlt dann eine Marke in die Spielkasse. Bei allen anderen Augensummen (d.h. weniger als 11) muss ein Spieler so viele Marken in die Kasse zahlen, wie ihm zur Augensumme 11 fehlen.

49 Wer kennt wen? Eine Möglichkeit zur Realisierung des Elf-hoch-Spiels nach den normalen Spielregeln besteht darin, dass nachdem ein Spieler mit einem 11er-Wurf die Kasse leergeräumt hat, dieser Spieler den Spielmanager beauftragt, von jedem Spieler erneut einen Einsatz einzufordern. Bei dieser Realisierung muss jedes Spieler-Objekt das Spielmanager-Objekt kennen, um ihm die passende Nachricht schicken zu können.

50 Hin- und Rück-Referenzen
Beachte, dass die Hin- und Rück-Referenzen zwischen dem Spielermanager-Objekt und einem Spieler-Objekt erst gesetzt werden können, wenn die betreffenden Objekte erzeugt sind. Der folgende Quelltext zeigt, wie das umgesetzt werden könnte. w1 = Wuerfel() w2 = Wuerfel() k = Kasse(0) sp1 = Spieler('Winner', 100, w1, w2, k) sp2 = Spieler('Looser', 100, w1, w2, k) sp3 = Spieler('Zitterhand', 100, w1, w2, k) m = Spielmanager(sp1, sp2, sp3) sp1.setSpielmanager(m) sp2.setSpielmanager(m) sp3.setSpielmanager(m) m.einsatzEinfordern() print(sp1.getMarken(), sp2.getMarken(), sp3.getMarken()) m.spielrundeDurchfuehren()

51 Modellierung Im Klassendiagramm wird die Beziehung zwischen einem Spielmanager-Objekt und einem Spieler-Objekt jetzt bidirektional (d.h. in zwei Richtungen weisend) dargestellt. Im Klassendiagramm sind auch bereits weitere Methoden aufgelistet.

52 Implementierung Aufgabe:
Ändere die bereits vorliegende Implementierung des Spiels Elf-hoch passend zum Klassendiagramm ab.

53 Das Spiel Elf-hoch Bisher haben wir das Spiel Elf-hoch immer mit drei Spielern simuliert. Das Spiel Elf-hoch kann man aber auch mit vier, fünf usw. oder auch mit nur zwei Spielern spielen. Interessant wäre auch, wenn sich die Spielerzahl während eines Spiels dynamisch verändern könnte. So wäre es sinnvoll, dass Spieler, die alle Spielmarken verloren haben, ausscheiden müssen. Im Folgenden soll es darum gehen, die Spieler bei der Simulation des Elf-hoch-Spiels dynamisch zu verwalten. Wir betrachten hier wieder nur die vereinfachte Spielversion.

54 Verwaltung von vielen Objekten
Eine Vielzahl an Objekten lässt sich gut mit einer Liste verwalten. In die Liste werden sämtliche Referenzen auf die zu verwaltenden Objekte gepackt. Die Datenstruktur Liste lässt zudem zu, weitere Referenzen der Liste hinzuzufügen oder auch Referenzen aus der Liste zu entfernen. Man erhält so eine Möglichkeit, eine Vielzahl an Objekten dynamisch zu verwalten.

55 Modellierung Im folgenden Klassendiagramm sind diese Operationen bereits vorgesehen. Beachte, dass die variable Anzahl der vom Spielmanager verwalteten Spieler mit dem Sternsymbol (für beliebig viele) gekennzeichnet ist.

56 Implementierung Aufgabe:
Ändere die bereits vorliegende Implementierung des Spiels Elf-hoch passend zum Klassendiagramm ab.

57 Beziehungsmuster Muster: Objekt der Klasse A kennt Objekt der Klasse B
Objekt der Klasse A erzeugt Objekt der Klasse B Muster: Objekt der Klasse A kennt Objekt der Klasse B und umgekehrt

58 Beziehungsmuster Muster:
Objekt der Klasse A kennt mehrere Objekte der Klasse B

59 Übung - Würfelbecher Würfelbecher werden benutzt, um Würfel so zu werfen, dass man keine Würfelergebnisse vorhersagen kann. Die Würfel werden hier nicht direkt geworfen, sondern man lässt sie aus dem Becher herausrollen. Dieser Vorgang soll mit geeigneten Software-Objekten simuliert werden. Der Würfelbecher soll mit einer festen Anzahl von Würfeln gefüllt werden (z.B. 3 Würfel). Entwickle eine Klasse zur Simulation eines solchen Würfelbechers.

60 Übung - Würfelbecher Aufgabe:
Die Klasse Wuerfelbecher soll jetzt so abgeändert werden, dass beliebig viele Wuerfel-Objekte verwaltet und aktiviert werden können.


Herunterladen ppt "Konzepte objektorientierter Programmierung: Beziehungen zwischen Objekten Klaus Becker 2016."

Ähnliche Präsentationen


Google-Anzeigen