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.

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.

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)

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)

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.

...
  def add_student(a_student):
    if not a_student in self._students:
      if len(self._students) < 24:
        self._students.append(a_student)

Diese Property liefert die Grösse der Liste.

  @property
  def count_students(self):
     return len(self._students)

Diese Methode dient dazu, ein bestimmtes Element aus der Liste zu lesen. Dies erfolgt entweder …

  • … über den Index des Listenelements
  • … einen eindeutigen Wert (Key)
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

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)
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)

Je nach Entwurf der Applikation können die take- und remove-Methoden auch nur einen der Parameter index bzw. key anbieten.


René Probst, bearbeitet durch Marcel Suter

  • modul/m320_2024/learningunits/lu09/mehrfachbeziehung.txt
  • Zuletzt geändert: 2024/09/23 09:11
  • von msuter