Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
de:modul:m320_2024:learningunits:lu09:mehrfachbeziehung [2026/08/30 14:05] – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1de:modul:m320_2024:learningunits:lu09:mehrfachbeziehung [2026/08/30 14:12] (aktuell) – ↷ Links angepasst, weil Seiten im Wiki verschoben wurden 74.7.243.195
Zeile 1: Zeile 1:
 +====== LU09a - Mehrfachbeziehung ======
 +
 +Aus der realen Welt sind Mehrfachbeziehungen bestens bekannt. 
 +So weist eine Schulklasse viele Lernende auf, eine Feriendestination kann von vielen Personen gebucht werden und umgekehrt kann eine Person viele Destinationen besuchen.
 +
 +Diese beiden Fälle können wie folgt in UML dargestellt werden.
 +
 +{{de:modul:m320_2024:learningunits:lu09:klasseschool.png?600|}}
 +
 +//Abb: 1:n Beziehung//
 +
 +
 +=== Kardinalität ===
 +Die Kardinalität gibt an, wie mengenmässig eine Beziehung aussieht.
 +Vereinfacht kann man von
 +  * 1:1 Beziehung (ein Objekt kennt genau ein anderes Objekt)
 +  * 1:n Beziehung (ein Objekt kenntviele andere Objekte)
 +  * n:n Beziehung (ein Objekt kennt viele andere Objekte und umgekehrt)
 +
 +sprechen. 
 +Dabei steht **n** für den Begriff 'viele'
 +Dies wird in der UML mit einem Stern (** * **) wiedergegeben. 
 +Der Stern steht für **0 bis unendliche viele** Beziehungen.
 +In der UML ist es aber auch möglich, die Kardinalität ganz genau zu spezifizieren. 
 +So ist in der Abbildung klar erkennbar, dass eine Schulklasse mindesten 15 aber maximal 24 Studenten haben kann.
 +
 +===== Umsetzung in Python =====
 +Kennt ein Objekt viele andere, gleichartige Objekte, werden die Referenzen in einer Liste festgehalten. 
 +Ein einheitlicher Prefix bei den Methodennamen hilft bei der Orientierung.
 +  * Die Methode für das **Zufügen** wird als **add**-Methode bezeichnet. Gegenüber dem Begriff **set** signalisiert **add**, dass eben mehrere Werte gesetzt werden können.
 +  * Die Methode für das **Zählen** der Listeneinträge wird als **count**-Methode bezeichnet.
 +  * Die Methode um ein Element **abzufragen** wird als **take**-Methode bezeichnet.
 +  * Die Methode für das **Löschen** wird als **remove**-Methode bezeichnet.
 +Für die oben dargestellte Klasse ''SchoolClass'' würde das dann wie folgt aussehen (unter Einhaltung der maximalen Grösse der Klasse)
 +
 +==== Beziehungen hinzufügen (**add**)====
 +<code python>
 +class SchoolClass:
 +  def __init__(self, designation):
 +   self._designation = designation
 +   self._students = []  # hier wird eine leere Liste bereitgestellt, die dann die Referenzen der Lernenden hält.
 +  
 +  def add_student(a_student):
 +    if len(self._students) < 24:
 +      self._students.append(a_student)
 +</code>
 +
 +=== Duplikate vermeiden ===
 +Die Methode ''add_student'' kann erweitert werden, um doppelte Einträge zu vermeiden.
 +Dazu prüfen wir zunächst, ob das ''student''-Objekt schon in der Liste vorhanden ist.
 +
 +<code python>
 +...
 +  def add_student(a_student):
 +    if not a_student in self._students:
 +      if len(self._students) < 24:
 +        self._students.append(a_student)
 +</code>
 +
 +==== Anzahl Listeneinträge abfragen (**count**) ====
 +Diese Property liefert die Grösse der Liste.
 +<code python>
 +  @property
 +  def count_students(self):
 +     return len(self._students)
 +</code>
 +
 +==== Lesen eines Objekts (**take**) ====
 +Diese Methode dient dazu, ein bestimmtes Element aus der Liste zu lesen.
 +Dies erfolgt entweder ...
 +   * ... über den Index des Listenelements
 +   * ... einen eindeutigen Wert (Key)
 +
 +
 +<code python>
 +def take_student(self, index=None, key=None):
 +  if index is not None:   # Index wurde angegeben
 +    if index < len(self._students):
 +      return self._students[index]
 +    else:
 +      raise StudentIndexError('search')
 +  else:   # kein Index angegeben, wir suchen nach dem Namen
 +    for student in self._students:  # Loop über alle student-objekte
 +      if student.name == key:
 +        return student
 +    return None
 +</code>
 +
 +
 +==== Löschen einer Beziehung (**remove**) ====
 +Diese Methode dient dazu, ein bestimmtes Element aus der Liste zu löschen.
 +Dies erfolgt entweder ...
 +   * ... über den Index des Listenelements
 +   * ... einen eindeutigen Wert (Key)
 +
 +<code python>
 +def remove_student(self, index=None, key=None):
 +  if index is not None:   # Index wurde angegeben
 +    if index < len(self._students):
 +      self._students.remove(idx)
 +    else:
 +      raise StudentIndexError('remove')
 +  else:   # kein Index angegeben, wir suchen nach dem Namen
 +    for idx, student in enumerate(self._students):  # Loop über alle student-objekte
 +      if student.name == key:
 +        self._students.remove(idx)
 +</code>
 +
 +<WRAP center round tip 60%>
 +Je nach Entwurf der Applikation können die **take**- und **remove**-Methoden auch nur einen der Parameter ''index'' bzw. ''key'' anbieten.
 +</WRAP>
 +
 +----
 +{{tag>M320-LU09}}
 +[[https://creativecommons.org/licenses/by-nc-sa/4.0/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] René Probst, bearbeitet durch Marcel Suter