Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Beobachter und Zustandsmuster

Nach dieser Lektion: Ich kann das Beobachtermuster und das Zustandsmuster anwenden.

Lektion, 70 Min.6 BefehleLab „Linux im Alltag“: die dreißig Befehle, die Entwickelnde auswendig tippen

Alle erfahren vom neuen Raum

Das Beobachtermuster (Observer) sorgt dafür, dass ein Objekt viele andere über eine Änderung informiert, ohne sie zu kennen. Das Zustandsmuster (State) lässt ein Objekt je nach Phase anders reagieren.

Der Raum einer Vorlesung ändert sich. Der Aushang, das Handy und die Webseite sollen es sofort zeigen. Eine Bestellung wiederum verhält sich je nach Phase anders.

Am Ende dieser Lektion

Notiz

Ich kann das Beobachtermuster und das Zustandsmuster anwenden.

Schlüsselwörter

BegriffWas er bedeutet
Beobachterein Objekt, das über Änderungen informiert werden will
Anmeldensich in die Liste der Beobachter eintragen lassen
Benachrichtigungder Aufruf, mit dem alle Beobachter von einer Änderung erfahren
Zustanddie Phase, in der sich ein Objekt gerade befindet
Übergangder Wechsel von einem Zustand in den nächsten

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Beobachter erfahren von einer Änderung, ohne zu fragen

Das Problem: Ein Objekt ändert sich, und mehrere andere müssen es wissen. Fragt jedes ständig nach, kostet das Zeit. Kennt das Objekt alle anderen fest, hängt es von ihnen ab.

Beim Beobachtermuster führt das Objekt eine Liste. Wer sich anmeldet, steht darin. Bei einer Änderung ruft es bei jedem Eintrag melden auf.

Ein Stundenplan mit zwei Beobachtern

Code: python
class Stundenplan:
    def __init__(self):
        self.beobachter = []

    def anmelden(self, beobachter):
        self.beobachter.append(beobachter)

    def raum_aendern(self, fach, raum):
        for beobachter in self.beobachter:
            beobachter.melden(fach, raum)

class Aushang:
    def melden(self, fach, raum):
        print("Aushang: " + fach + " jetzt in " + raum)

class Handy:
    def __init__(self, name):
        self.name = name

    def melden(self, fach, raum):
        print(self.name + " erhält: " + fach + ", Raum " + raum)

plan = Stundenplan()
plan.anmelden(Aushang())
plan.anmelden(Handy("Mia"))
plan.raum_aendern("Mathe", "B12")
# Melden Sie ein zweites Handy an und ändern Sie den Raum noch einmal.

Was beim Raumwechsel passiert

SchrittWerWas geschieht
1Aushangmeldet sich mit anmelden an
2Handy von Miameldet sich an
3Stundenplanraum_aendern("Mathe", "B12") läuft
4Stundenplanruft melden bei Aushang und Handy auf, in der Reihenfolge der Anmeldung

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Ein häufiger Fehler

Warnung

Viele vergessen das Abmelden. Ein Beobachter, der nicht mehr gebraucht wird, steht dann weiter in der Liste und bekommt jede Nachricht. Bieten Sie neben anmelden immer auch abmelden an.

Zustandsmuster: je Phase ein Objekt

Das Problem: Eine Bestellung ist offen, bezahlt oder versendet. Was erlaubt ist, hängt davon ab. Eine Kette von if zustand == ... steht dann in jeder Methode.

Beim Zustandsmuster ist jede Phase ein eigenes Objekt mit denselben Methoden. Die Bestellung hält das aktuelle Zustandsobjekt und gibt Aufrufe an es weiter. Ein Übergang heißt: Das Zustandsobjekt nennt den nächsten.

Eine Bestellung wechselt ihre Phase

Code: python
class Offen:
    def name(self):
        return "offen"
    def weiter(self):
        return Bezahlt()
class Bezahlt:
    def name(self):
        return "bezahlt"
    def weiter(self):
        return Versendet()
class Versendet:
    def name(self):
        return "versendet"
    def weiter(self):
        return self
class Bestellung:
    def __init__(self):
        self.zustand = Offen()
    def weiter(self):
        self.zustand = self.zustand.weiter()
bestellung = Bestellung()
for schritt in range(4):
    print(bestellung.zustand.name())
    bestellung.weiter()

Die Zustände der Bestellung im Überblick

Zustandname() liefertweiter() liefert
OffenoffenBezahlt
BezahltbezahltVersendet
Versendetversendetsich selbst, die Bestellung ist am Ende

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Eine Ampel und eine Quelle im Lab

Im Lab laufen zwei kleine Programme. Die Datei ampel.py zeigt eine Ampel als Zustandsobjekte: Rot, Gruen, Gelb, und dann wieder Rot.

Die Datei quelle.py zeigt einen Beobachter ohne Klasse: Zwei Funktionen melden sich an. Die Ausgabe folgt aus den Programmen selbst.

Den Ordner anlegen

Befehl
mkdir -p ~/oop-labor

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Hineingehen

Befehl
cd ~/oop-labor

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Ampel mit drei Zuständen schreiben

Befehl
printf 'class Rot:\n    def weiter(self):\n        return Gruen()\n\n    def farbe(self):\n        return "Rot"\n\nclass Gruen:\n    def weiter(self):\n        return Gelb()\n\n    def farbe(self):\n        return "Gruen"\n\nclass Gelb:\n    def weiter(self):\n        return Rot()\n\n    def farbe(self):\n        return "Gelb"\n\nzustand = Rot()\nfor schritt in range(5):\n    print(schritt, zustand.farbe())\n    zustand = zustand.weiter()\n' > ampel.py

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Ampel starten

Befehl
python3 ampel.py

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Eine Quelle mit zwei Beobachtern schreiben

Befehl
printf 'class Quelle:\n    def __init__(self):\n        self.hoerer = []\n\n    def anmelden(self, hoerer):\n        self.hoerer.append(hoerer)\n\n    def senden(self, text):\n        for hoerer in self.hoerer:\n            hoerer(text)\n\ndef erster(text):\n    print("Erster: " + text)\n\ndef zweiter(text):\n    print("Zweiter: " + text)\n\nquelle = Quelle()\nquelle.anmelden(erster)\nquelle.anmelden(zweiter)\nquelle.senden("Hallo")\nquelle.hoerer.remove(erster)\nquelle.senden("Tschuess")\n' > quelle.py

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Die Quelle starten

Befehl
python3 quelle.py

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Beobachter müssen keine Klassen sein

Die Quelle ruft jeden Eintrag wie eine Funktion auf. Es genügt also eine Funktion, die einen Text annimmt. Nach dem Abmelden hört nur noch zweiter zu: Zweiter: Tschuess.

Die Ampel zeigt: Jedes Zustandsobjekt kennt nur seinen Nachfolger. Ein vierter Zustand ändert nur den Zustand davor.

Über dieses Lab und seinen Quellcode: Lab „Linux im Alltag“: die dreißig Befehle, die Entwickelnde auswendig tippen

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.