Im Lager wird ein Artikel entnommen. Das ist ein kleiner Vorgang â eine Zahl wird kleiner. Aber es hĂ€ngt einiges daran:
public void Entnehme(string artikel, int menge)
{
_bestand[artikel] -= menge;
if (_bestand[artikel] < _mindestbestand[artikel])
{
_nachbestellung.Beauftrage(artikel);
_email.Sende(_einkauf.Adresse, $"{artikel} unter Mindestbestand");
_dashboard.Aktualisiere(artikel, _bestand[artikel]);
_protokoll.Schreibe($"Unterschreitung: {artikel}");
}
}Die Klasse Lager hat eine Aufgabe: BestĂ€nde fĂŒhren. Inzwischen kennt sie die Nachbestellung, den Mailversand, das Dashboard und das Protokoll. Vier AbhĂ€ngigkeiten, die mit BestĂ€nden nichts zu tun haben.
Der Preis dafĂŒr fĂ€llt an drei Stellen an:
- Der Konstruktor wĂ€chst. Jede neue Reaktion ist eine neue AbhĂ€ngigkeit â und jeder Test von
Lagermuss sie mitliefern, auch wenn er nur prĂŒft, ob richtig subtrahiert wird. - Die Reihenfolge wird zur Vorschrift. Steht der Mailversand vor der Nachbestellung, ist das eine Entscheidung, die niemand bewusst getroffen hat â sie ergibt sich aus der Zeilenreihenfolge.
- Ein Fehler reisst alles mit. Wirft
_email.Sendeeine Exception, weil der Mailserver weg ist, wird die Nachbestellung nicht mehr beauftragt. Der Bestand wurde aber schon verÀndert.
Die Richtung der AbhÀngigkeit
Der Kern des Problems ist eine Richtung: Lager zeigt auf vier EmpfĂ€nger. Dabei interessiert sich Lager fĂŒr keinen von ihnen â sie interessieren sich fĂŒr Lager. Observer dreht genau diesen Pfeil um.
Die Idee
Das Lager sagt nicht mehr «Nachbestellung beauftragen, Mail senden, Dashboard aktualisieren». Es sagt nur noch:
Der Bestand von Artikel X ist unter den Mindestbestand gefallen.
Wer damit etwas anfangen will, meldet sich vorher an. Das Lager kennt seine Zuhörer nicht â es weiss nicht einmal, ob es welche gibt.
Damit Ă€ndert sich die Antwort auf «Was passiert bei einer Unterschreitung?»: Sie steht nicht mehr im Lager, sondern bei denen, die zuhören. Das ist gleichzeitig der Gewinn und die Gefahr dieses Patterns â dazu in der dritten Lektion mehr.
Wann Observer passt
Wenn ein Vorgang eine Tatsache meldet («ist passiert») und nicht einen Auftrag erteilt («tu das»). Muss der Sender wissen, ob die Reaktion geklappt hat, ist Observer das falsche Werkzeug â dann ist ein direkter Aufruf ehrlicher.