Abschlussprojekt: Eine gemeinschaftliche Leihbibliothek · Übung
Sichere Momentaufnahmen von Sammlungen zurückgeben
Die Bibliothek hat drei private Dictionarys. Niemand kann bisher sehen, was darin liegt. Zwei Operationen der Schnittstelle sollen das ändern:
available_items()
active_loans()
Interessant ist, wie die Zusage die erste beschreibt:
available_items()macht aktuell ausleihbare Objekte zugänglich, ohne veränderliche interne Sammlungen offenzulegen.
Dieser Satz ist die Lektion.
Änderungen durch die Methoden von Library kontrollieren
Die drei Dictionarys dienen der privaten Verwaltung von Library. Sie zu verwalten bedeutet, auch ihre Änderungen zu kontrollieren: Jede tatsächliche Änderung sollte durch eine Methode gehen, die die Regeln der Bibliothek durchsetzt.
Würde available_items einfach self._items zurückgeben, könnte jeder Aufrufer schreiben:
shelf.available_items()["sneaky"] = a_book
Der Katalog hätte damit einen Gegenstand hinzugewonnen, ohne add_item zu durchlaufen, den einzigen Ort der Regel gegen doppelte IDs. Die Zugangskontrolle aus Lektion 3 stünde neben einer offenen Seitentür.
Deshalb erstellen diese Methoden etwas Neues und geben es zurück. Lektion 2 aus Kapitel 13 testete genau diese Zusage auf Quiz.questions(). Hier wirst du sie ebenfalls testen.
Was herausgegeben wird und was nicht
Sei genau darin, was „ohne offenzulegen“ umfasst. Es ist leicht, zu weit zu gehen.
Die zurückgegebene Sammlung muss eine neue Liste sein, getrennt von den eigenen Sammlungen der Bibliothek. Wenn ein Aufrufer etwas an seine Rückgabe anhängt, ändert das nichts.
Die enthaltenen Gegenstände sind die echten Book- und Game-Objekte. Das ist beabsichtigt. Ein Aufrufer braucht sie: Den Katalog auszugeben bedeutet, Titel von tatsächlichen Gegenständen zu lesen. Würden die Gegenstände kopiert, sähe der Aufrufer veraltete Doppelgänger, was schlechter wäre.
Das ist eine flache Momentaufnahme: Sie schützt die Zusammensetzung der Sammlung, nicht die veränderlichen Gegenstände darin. Eine Änderung des Titels bleibt über andere Referenzen sichtbar. Die item_id ist allerdings für die Bibliothek wichtig. Aufrufer müssen Kennungen nach der Registrierung deshalb unverändert lassen. Eine vollständigere Anwendung könnte das mit schreibgeschützten Properties erzwingen. In diesem Projekt laufen Ausleih- und Verfügbarkeitsänderungen über Library, während registrierte Kennungen als stabil gelten.
Verfügbarkeit wird abgeleitet, nicht gespeichert
Nirgendwo gibt es ein Kennzeichen is_available. Eines hinzuzufügen wäre ein Fehler.
Ein Gegenstand ist genau dann verfügbar, wenn keine aktive Ausleihe ihn nennt:
def available_items(self):
return [
item
for item_id, item in self._items.items()
if item_id not in self._loans
]
Das ist dieselbe Überlegung wie beim Zählen der Ausleihen in Lektion 5. Ein Kennzeichen hält ein zweites Mal fest, was die Ausleihen bereits sagen. Beide können widersprüchlich werden: Vergisst du bei einer Rückgabe die Anpassung, bleibt ein Gegenstand, den niemand hat, für immer unsichtbar. Abgeleiteter Zustand kann nicht auseinanderlaufen, weil es nur eine maßgebliche Aufzeichnung gibt.
Die Bibliothek speichert kein Kennzeichen is_available auf Gegenständen. Was bringt das?
Aktive Ausleihen
active_loans() wendet dieselbe Zusage auf die andere Sammlung an: Gib die aktuellen Ausleihen in einem Container zurück, den du herausgeben darfst.
Die Ausleihen selbst brauchen keinen Schutz. Sie sind eingefroren, wofür Lektion 4 sich teilweise genau wegen dieses Moments entschied: Ein Aufrufer kann die echten Ausleihobjekte erhalten, ohne sie ändern zu können. Das ist der Nutzen eines Wertobjekts und der Grund, warum active_loans einfacher ist als available_items, obwohl beide dieselbe Aufgabe erfüllen.
Aufgabe
Implementiere available_items und active_loans in library.py.
available_items() gibt eine Liste der Gegenstandsobjekte zurück, die gerade nicht ausgeliehen sind, und zwar in der Reihenfolge, in der sie dem Katalog hinzugefügt wurden.
active_loans() gibt eine Liste der aktuellen Loan-Werte zurück.
Beide geben jedes Mal eine neue Liste zurück. An die Rückgabe anzuhängen darf die Bibliothek nicht verändern. Keine der Methoden darf ein eigenes Dictionary der Bibliothek oder eine Ansicht darauf herausgeben.
Leite die Verfügbarkeit aus den Ausleihen ab. Füge Gegenständen kein Verfügbarkeitskennzeichen hinzu.
Lass overdue_loans weiterhin NotImplementedError auslösen.