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
Die Kardinalität gibt an, wie mengenmässig eine Beziehung aussieht. Vereinfacht kann man von
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.
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)
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 …
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 …
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.