Sie sehen dort geschrieben, Sie sehen dort geschrieben, Vorlesung 7.
Wer von Ihnen hat sich die Folien gestern,
beziehungsweise bis heute, sagen wir mal, so 13 Uhr runtergeladen?
Wenn Sie da jetzt mal so ein kleines,
einen kleinen Unterschied feststellen wollen, da ist schon einer.
Den Folien gestern hieß es Vorlesung 8. Das habe ich nicht
bewusst wieder rückgängig gemacht. Ehrlich gesagt weiß ich es ja selber nicht,
ob wir uns in Vorlesung 7 oder 8 befinden,
weil je nachdem, wie man zählt,
ist es die siebte Vorlesung, aber es ist die achte Semesterwoche,
wie dem auch sei
Viele von ihnen werden die Unterschiede also nicht bemerken zwischen den Foliensatz,
den ich gestern reingestellt habe und den ich heute korrigiert,
wieder reingestellt habe.
Das da ist auf jeden Fall der Satz, den ich jetzt zeige,
ist er, den sie auch im Komsi finden.
So, das dazu. Zweite Vorbemerkung, ausgegebenem Anlass.
Das Modul SE2 besteht aus zwei Teilen.
Einteilen ist die Übungen, da können sie
einen Übungsschein machen
Der zweite Teil ist die Klausur. Die können sie schreiben.
Diese beiden Teile sind unabhängig voneinander. Also wenn sie,
aus welchen Gründen auch immer, sagen,
ich will den Übungsschein nicht dieses Semester machen oder die Schurken geben ihnen mir nicht den Übungsschein,
hindert sie das in keiner Weise daran, an der Klausur mitzuschreiben.
Tun sie das. Wenn sie den Übungsschein haben und
die Schurken sagen, sie haben zu wenig Punkte,
um das zu bestehen, dann kommen sie zur Wiederholungsprüfung.
Und wenn sie beide Teilprüfungen bestanden haben, dann kriegen sie
diesen Modul, diesen Modul in den Scheiden Nachweis. So,
ich erzähle Ihnen das ungefähr so gerne, wie ich über Fußpilz spreche,
weil ich rede mit Ihnen eigentlich lieber über Entwurfsmuster,
aber es ist mir angetragen worden, das hier nochmal anzusagen,
weil es da wohl Missverständnisse gab.
Unter anderem, dass der Übungsschein Voraussetzung sei, um an der Klausur teilzunehmen.
Das ist nicht der Fall. So, können Sie das
jetzt bitte alle aufschreiben, was ich gerade gesagt habe?
Und dann abzeichnen und ich sammle diese Zettel nachher ein als Beleg dafür,
dass Sie das verstanden haben, wovon ich spreche.
Ansonsten wird diese Frage in der Klausur nicht mehr gestellt werden,
brauchen sich keine Sorgen zu machen
Ja. Also, öfter nichts machen. Das ganze Teil
hier unterscheidet sich nun die Wegsie von allen anderen Sachen.
Die Frage war, ob sich dieses Teil durch irgendwas unterscheidet von
allen anderen Teilen. Diese Frage ist für mich nicht beantwortbar.
Kann ja sein, dass auch andere Veranstaltungen so organisiert sind.
Es gibt einen Übungsteil und es gibt einen Vorlesungsteil und die
sind unabhängig voneinander, wenn das die Frage ist,
ja,
mag so sein
Ich kenne mich da nicht aus. So, jetzt aber. Heute, Vorlesung 7 bis 8. Heute werden wir uns mit einem Thema beschäftigen, das heißt Entwurfsmuster. Ach so,
in unserer Reise, auf dem Weg zu großen Softwaresystemen,
die von Teams von 7 bis 10 oder noch mehr Personen über einen Zeitraum von mehreren Monaten geschrieben werden,
haben wir ja schon mal so ein paar Versatzstücke,
haben wir jetzt aufgesammelt,
also von den Von den kleinen Bausteinen der Objektorientierten Programmierung über die ganze Frage der modularisierung des Six des gesitteten Umgangs mit Exceptions,
das Vertragsmodell bis hin zu dem,
womit wir uns logisch letzte Woche beschäftigt haben,
was Fred ja dann auch in seinem Teil letzte Woche vorgetragen hat,
so eine Art Architektur,
Blaupause im Großen,
nämlich so der Werkzeugmaterialansatz,
also eine Idee,
wie können Softwaresysteme
im Großen strukturiert werden
Zeichnet das auch, also so diese Strukturierung im Großen auch als Makroarchitektur.
Ich komme gleich noch ein bisschen genauer darauf zu sprechen. Folien,
die Sie ausgedruckt haben könnten, beziehungsweise die Sie sich im Komsi anschauen können,
sehen Sie auch eine Definition, zum Thema Softwarearchitektur.
Das Thema Entwurfsmuster beleuchtet einen weiteren Aspekt, nämlich die sogenannten Mikroarchitekturen für großes Softwaresystem.
Und dem Thema werden wir uns jetzt in den nächsten 80 plus Minuten widmen.
Das hat jetzt noch wenig mit Softwareentwicklung zu tun, Leitet uns,
aber schon mal über in das, wo ich jetzt,
worauf ich hinaus will, wenn ich über Softwaresysteme im Kleinen und deren Strukturierung spreche.
Und da gucken Sie jetzt drauf und denken,
ist das gutes Design, das denken Sie möglicherweise nicht,
sondern es ist unmittelbar unmittelbar klar, das entspricht nicht unserer Alltagserfahrung,
was Sie da sehen, Und ähnlich ist das Problem hier,
da werden Dinge zusammengeführt, die offensichtlich, also offensichtlich,
das kann ich hier nur noch mal betonen,
nicht zusammenpassen.
Lebensgefährlich will es an der Stelle, das passt auch nicht wirklich.
Und ja, ja, oh Gott. Da will man
eigentlich auch nicht drin wohnen. Jedenfalls nicht. Also wenn
man zu regelmäßigem Alkoholkonsum neigt, das ist jetzt nicht lebensgefährlich.
Das sieht einfach nur aus wie Apropos Alkoholkonsum, die,
die das eingebaut haben, also standen die möglicherweise unter Drogen,
weiß ich, hier passiert ist.
Das ist jetzt das Letzte. Die Reihe geht,
das Original geht noch weiter. Aber das sind so die
Beispiele für so misslungene Architektur. So, und wenn jetzt,
also, wenn wir jetzt uns das mal anschauen und die Betonung liegt hier auf Anschauen,
ist ja, ich habe schon mal darüber gesprochen,
welchen großen Vorteil diese anderen Wissenschaften uns Softwareentwicklern gegenüber haben.
Einer der Vorteile, denen man hat, den wir alle haben,
wenn wir auf so etwas schauen, ist,
dass unmittelbar durch die Verwendung unserer Sinne und die Erfahrung,
die wir haben, im Umgang mit Architektur, können wir erkennen, da ist was faul.
Und die Architekten selbst, das ist jetzt so ein Beispiel für,
wenn man so will, ist das so eine Art,
also wiederum eine Art von Transdisziplinäre Herangehensweise, der jetzt im weiteren Folgen wird.
Die Architekten selbst haben, also auch schon so eine eigene Sprache dafür entwickelt,
wie man gute Entwürfe und damit eben im Umkehrschluss auch schlechte Entwürfe,
wie man die erkennen kann.
Und für die guten Entwürfe gibt es eine sogenannte Mustersprache.
Und der Architekt, der da eine ganz besondere Rolle gespielt hat,
ist ein Mensch namens Christopher Alexander. Und der hat also eine Mustersprache,
eine Pattern Language für die Entwicklung Architekturen, nicht nur im Kleinen,
so nach dem Muster, also baue mal eine Treppe immer an der Stelle,
wo es also ein Stück nach oben geht.
Das sind etwas elaboriertere Muster. Ich verstehe da auch nur ganz,
ganz, ganz am Rande von etwas, aber die Grundidee,
wie man ein Problem lösen kann, die ist vergleichbar mit dem,
worüber ich jetzt die nächsten Minuten sprechen will,
was der entwickelt hat,
ist eine Mustersprache derart,
dass Architekten für wiederkehrende Problemstellungen
auf bewährte Muster zurückgreifen können
Das ist so die Grundidee dieses Katalogs von Mustern,
Patterns, die Christopher Alexander als Erster so in die Architektur,
am Ende des letzten Jahrhunderts eingebracht hat.
Und diese Idee wurde jetzt von Softwareentwicklern namentlich Erich Gamma und anderen Ende des letzten Ende des letzten Jahrhunderts,
wurde die aufgenommen, um mal zu überprüfen, ob wir,
wir Softwareentwickler unter der Verwendung von Mustern, genauer gesagt,
Entwurfsmustern,
nicht auch einen Beitrag zur besseren Strukturierung,
zur besseren Kommunikation,
über Softwaresysteme leisten können
Ja, und die Frage kann man nur mit einem klaren Ja beantworten.
Jetzt haben Sie gerade, haben Sie diese Beispiele für schlechte Architektur im Kleinen
, haben Sie gesehen. Und ich habe darauf,
schon darauf hingewiesen, das ist also für schlechte Architektur,
ist das vergleichsweise einfach, die zu erkennen,
weil sie eben unmittelbar sinnlich erfahrbar ist,
was die schlechte Architektur von Softwaresystemen anbetrifft, haben wir es etwas schwieriger.
Die entzieht sich ja unseren Sinne. Das Einzige,
was wir eigentlich machen können, ist,
wir drucken Source Code aus oder wir gucken uns den am Bildschirm an,
aber was da für eine Architektur hinter steckt,
das sieht man ja nicht.
Das ist ja
sein geistiges Konstrukt
Und das, was sie jetzt hier sehen,
ist also ein Beispiel für ein mittelgroßes, mittelgroßes, um nicht zu sagen kleines Softwaresystem.
Und der Versuch, die Beziehungen, die zwischen den einzelnen Elementen in diesem Softwaresystem existieren, einmal grafisch darzustellen. Und das so,
wenn sie jetzt mal diese Fensterkonstruktion oder diese Treppenkonstruktion betrachten,
das, was also ein erfahrener Benutzer eines Hauses sofort sieht,
da ist was falsch und nicht etwa an der Stelle,
das sieht also ein erfahrener Softwarearchitekt,
wenn der auf so eine Struktur schaut, dann,
also das heißt dann in der Terminologie der Softwarearchitekten auch so,
der sieht sofort, also von der Metaphorik her auch schräg,
der sieht sofort ein Bad Smell.
Also der sieht, dass da etwas komisch riecht.
Und das, was da komisch riecht, sind,
also sind zwei Elemente oder sind zwei Fakten.
Da oben sehen sie das. 30 Prozent der Klassen sind in sogenannten Klassenzyklen enthalten. Klassenzyklen,
wir haben das schon mal besprochen, Klassenzyklen sind,
also Bösen, weil Klassen, die sich in Zyklen befinden,
nicht unter anderem, nicht unabhängig voneinander testen lassen.
Sie sind immer, es gibt keine eindeutige Hierarchie,
deswegen heißt es ja auch Zyklus,
die sind wechselseitig voneinander abhängig, ich kann die auch nicht,
also die Elemente, die in einem Zyklus sind,
nicht mal separiert auf verschiedenen Rechnern laufen lassen,
einfach weil die zyklisch miteinander verbunden sind.
Darauf werden wir, das wird im weiteren Teil,
im weiteren Verlauf der Vorlesung noch eine Rolle spielen. Der zweite Bad Smell,
der da entdeckbar ist, ist die sogenannte Gottklasse,
die heißt so, weil Sie sehen das hier,
so in diesem Entwurf, so man kann fast,
also sagen, das ist etwas, eine Fähigkeit,
die sie auch im Laufe der Jahre wahrscheinlich hoffentlich entwickeln werden.
Sie können manchen Entwürfen von Software-Systemen, die Organisationsstruktur der Teams
anschauen, in denen diese Entwürfe hervorgebracht worden sind.
Und dieser Entwurf riecht danach,
dass die so zwei Chefentwickler haben und der eine heißt Problem
A und der andere heißt Problem
Die beiden delegieren, also das, wozu sie keine Lust
haben oder was sie glauben, was die anderen machen können,
eben an diese, an die Leute, die ihnen zuarbeiten.
Und die haben jetzt so eine Struktur hergestellt,
die also merklich unausgewogen ausschaut, weil wenn Problem A,
21 Klassen kennt und von 49 benutzt wird und bei dem
hier sieht das ähnlich aus und die anderen Klassen stehen einfach nicht in einem gesunden Verhältnis zu denen,
dann ist das für die Weiterentwickelbarkeit für die Wartbarkeit das andere nicht funktionale Kriterien,
Qualitätskriterien für Softwaresysteme anbetrifft, dann ist das ein schlechtes Zeichen.
Das heißt also, wir müssen,
nur jetzt auf der konstruktiven Seite, fragen wir uns jetzt mal,
gibt es Möglichkeiten über der Ebene der reinen syntaktischen Verwendung von Bausteinen,
gibt es Strukturierungsmöglichkeiten, die es uns ermöglicht, die es uns ermöglichen,
Systeme so zu strukturieren, dass man größere Strukturen wiedererkennen kann.
Nehmen wir nochmal das Beispiel der Architektur, also das Häuslebaus,
Man kann ja, selbst bei dieser, bleiben wir mal bei der,
bei diesem Bild, also von der Treppe unter dem Fenster.
Was man ja behaupten kann, ist, na die Steine sind,
da sind Steine verwendet worden und es sind also Fensterelemente verwendet worden. Und jemand,
der sich nicht mit Häusern auskennt, könnte er jetzt sagen,
ja gut, also diese beiden Elemente sind verwendet worden,
dass das jetzt der intendierten Verwendung von demjenigen,
der mal Steine und Häuser so zusammengestellt hat,
gesagt hat, bau jetzt mal ein Häuse, Häusele,
dass das nicht dessen Intention entspricht, diese Bausteine jetzt insgesamt zusammengesetzt worden sind, das sieht man den Bausteinen ja nicht an.
Dazu braucht es ja Wissen über die zukünftige Verwendung des Hauses,
des Fensters, der Treppe in diesem Fall. Und genauso kann man ja argumentieren,
sie kennen jetzt Klassen, sie kennen, benutzt Beziehung,
sie kennen, Vererbungsbeziehung,
sie kennen Packages und sie kennen noch viel mehr,
aber es sagt ihnen niemand, wie sollen sie diese Bausteine verwenden,
um ein Problem zu lösen,
dass sie möglicherweise vorher schon mal gesehen haben oder dass
andere für sie schon mal gelöst haben
Das sagen Ihnen diese Bausteine nicht.
Und das sind jetzt Entwurfsmuster, die Ihnen helfen sollen.
Diese Frage zu beantworten. Also die Idee, Sie sind,
Gott weiß, dass ich die Wahrheit spreche.
Sie sind nicht die Ersten, die objektorientierte Software entwickeln.
Jetzt sitzen Sie da vor Ihrem Rechner und möchten das Erfahrungswissen der Welt darüber,
was kann man denn alles so falsch machen in einer bestimmten Programmiersituation,
hat dieses Problem schon mal jemand gelöst,
beziehungsweise hat jemand schon mal dieses Problem gehabt und gesagt,
es ist unlösbar
Das wohl nicht. Aber so, wie sehen denn die Lösungsmöglichkeiten aus,
die andere schon mal in einer vergleichbaren Situation gefunden haben?
Das möchten Sie doch gerne wissen. Und wenn Sie so,
ich sehe jetzt von meinem Geistigen,
sehe ich Sie, von meinem geistigen Auge,
dann möchten Sie doch an so eine Schrankwand gehen und sagen,
also das Problem, das ich gerade habe,
das ist durch folgende Charakteristiker, kann das beschrieben werden?
Gibt es für dieses Problem eine Lösung, auf die ich
jetzt zum Teufel auch, also nicht von selbst komme?
Und das ist das, was dieser Musterkatalog Einen Musterkatalog für
sie erledigen soll. Diese Fragen leichter zu beantworten.
Er muss nach Katalog von Christopher Alexander beinhaltet 253 Muster.
Der Musterkatalog, den wir Ihnen hier vorstellen werden,
beinhaltet, glaube ich, 23 Muster.
Wir können die am Ende der Vorlesung mal durchzählen.
Und ich werde Ihnen heute eins vorstellen.
Das erste, das erste. Um nicht zu sagen,
das Wichtigste. Aber nein, das ist es nicht.
Ich werde Ihnen mal eins versuchen nahezulegen. So. Das Problem,
an dem ich das versuchen werde, dieses Entwurfsmuster zu motivieren
, steht da
Eine 1-zu-End-Beziehung zwischen Objekten, sodass die Änderung des Zustands eines Objekts dazu führt,
dass alle abhängigen Objekte benachrichtigt und automatisch aktualisiert werden.
Wie kann jemand auf die Idee kommen, dieses Problem zu haben?
Machen wir uns mal kurz klar, in welcher Art von
Kommunikationssituation wir uns hier befinden. Dies dadurch charakterisiert,
ich bin ein Objekt und sie sind ganz viele Objekte,
dass sich jeder einzelne von ihnen auch eins und wenn ich mich aktualisiere,
sprich, wenn irgendwas aus meinem Mund rauskommt,
dann möchte ich,
dass sich ihr Zustand verändert.
Ich möchte nämlich,
dass sie das hören
Ja, dann verändert sich ihr Zustand. Sie werden so langsam müde,
Blutdruck sinkt, die Muskel, die Spannung, verringert sich.
Spätestens 15.40 Uhr werden sie wieder langsam wach und gehen nach Hause.
Ein Element dieser Kommunikationssituation ein weiteres Element unserer Kommunikationssituation besteht darin.
Sie können mich alle gleichzeitig hören.
Das machen wir uns im Alltag nicht klar.
Also das ist einfach so. Das nehmen wir als gegeben
hin.
Wäre ich
ein Java-Objekt
Und würde Ihnen meine Zustandsänderung mitteilen wollen,
dann könnte ich das nicht Ihnen, den Abhängigen,
von mir abhängigen Objekten, allen gleichzeitig mitteilen.
Dann würde unsere Kommunikation so aussehen. Hesi, ich spreche
mit Ihnen. Nein, wird die so nicht aussehen.
Das war jetzt eine Methan-Bemerkung. Also die Kommunikation würde
so aussehen, ich sage jetzt was.
Zu Ihnen. Und dann würden Sie vielleicht noch sagen,
ja, ich habe es gehört.
Okay, dann ist der Kontrollfluss wieder bei mir.
Ich sage jetzt was
Und dann habe ich so eine Reihenfolge und ich wusste also alle meine,
wie viel sind sie so, 1050 Beobachter, müsste ich abklappern.
Und jedem Einzelnen sequenziell sagen, was ich denn jetzt zu sagen habe.
Und das sind halt die Randbedingungen einer objektorientierten, gängigen,
objektorientierten Programmiersprache, wenn ich diese Kommunikationssituation,
die da beschrieben ist, wenn ich die realisieren will.
Ja, bitte. Alternative, da könntest du eigentlich so machen,
dass da für alle Bälle,
die da schon die Objekte abkennen,
bei der Professionstats,
das schreibt zu einer Objekte
Das ist der Stadtdessen, das eins für ihn noch der Gefrage,
ob es sich geändert hat. Darum könnten wir verhindern,
dass das Objekt bei jeder seinen Änderungen hatte, seine ähnlichen,
viele brav ist. Ja, also der kommilitonisch schlägt schon,
ist schon mitten in der Diskussion, die ich jetzt gerade eröffne.
Stay tuned. Also wir reden weiter darüber. Also jetzt erstmal,
was ich hier geschaffen habe, ist,
also ich habe mir jetzt erstmal so ein Problem identifiziert,
ein Objekt ändert sich und andere sind daran interessiert von dieser Änderung zu erfahren.
Wie können wir uns diesem, Wie können wir dieses Problem näher,
das Problem ist klar, wie können wir dieses Problem grundsätzlich lösen?
Das Beispiel, was dem Fred seine Regular Expression ist im Guido sein Konto, sein Überweiser.
So, wir gucken uns jetzt erstmal das ja an.
Ich möchte so etwas wie ein Überweiser schreiben und so,
wie sie das gelernt haben, habe ich das jetzt auch gemacht.
Also habe ich den implementiert. Es gibt also Operationen,
mit denen ich den Zustand verändern kann. Es gibt Operationen,
mit denen ich den Zustand sondieren kann. Und es gibt sogenannte Prädikate,
mit denen ich also mit dem ich noch detaillierter Informationen über,
also das, was in dem Überweiser gerade los ist, nachfragen kann. Beispielsweise,
sag ich mal, ich kann also dem,
ich kann sagen, wem ich was überweisen möchte,
ich kann die Überweisung public Boyd überweisen,
ich kann also mit einem übergebenen Betrag,
kann ich tatsächlich etwas überweisen, ich kann mir sagen lassen,
wer ist denn, wer hat denn jetzt eigentlich,
nicht wer, sondern wie hoch ist denn der Kontostand,
dass Saldo beim Empfänger,
also eine Mischung aus verändernden und sondierenden Operationen bei dem Überweiser.
Ich kann Sind nicht den Überweiser so implementiere?
Kann ich also Testklasse dazu schreiben? Und mal schauen,
ob nach einer Überweisung sich die Kontostände,
die Salden bei den Empfängern und bei dem anderen,
ob die sich so verändert haben, wie ich das erwarte.
Das heißt, insbesondere, dass also der interaktive Kontext,
in dem ich den überweise, verwende,
der ist ganz unabhängig von der funktionalen Schnittstelle des Überweisers.
Der hat halt so ein paar Operationen, die er zur Verfügung stellt.
Und sollte ansonsten keine Annahmen über die Art,
seiner Benutzung machen. Da oben die Schnittstelle,
die drei Arten von Operationen hebt es schon kurz gesagt,
die uns generell zur Verfügung stehen,
die sind da und ansonsten mache ich keine Annahmen darüber.
Was ich aber tun möchte, ist, jetzt steht da schon,
also macht keine Annahmen über die Verwendung durch eine Grafikkomponente.
Ich möchte den jetzt mal interaktiv benutzen. Das ist ja nichts Verwerfliches,
dass man mal online etwas überweisen möchte dazu,
brauche ich jetzt,
muss ich
zwei Aufgaben lösen
Das eine ist, so wenn ich den interaktiv benutze,
dann kommt so ein, das ist jetzt,
finde ich, sehr lyrisch ausgedrückt,
also wird auf diesen Überweiser ein Strom von Ereignissen einprasseln, runterregnen.
Sie wissen, wovon ich spreche. Also da werden Beträge werden eingegeben,
Knöpfe werden gedrückt, Mäuse werden, also über die Oberfläche gezogen,
durch diese interaktiven Ereignisse, die muss ich entgegennehmen können.
Ich möchte gleichzeitig möchte ich, und das ist so ein ganz hehres Ziel,
also jede Softwareentwicklung. Wir hatten ja auch schon davon gesprochen,
ich möchte fachliche Entscheidungen, was ist ein Überweiser überhaupt und technische Entscheidungen,
wie wird das Ding in seiner interaktiven Umgebung benutzt,
die möchte ich voneinander trennen.
Ich möchte die nicht in einer Entwurfseinheit zusammenfassen. So,
das sind die beiden Aufgaben, die ich erfüllen möchte.
Wenn ich jetzt den Überweiser implementiere, ich hasse das aber.
Also da oben kommt also immer der Kontext,
der Strom von Ereignissen, also regnet herunter,
Das heißt, die generelle Richtung der Interaktion ist,
von einer Klasse, die ich mal Interaktion nenne,
gehen die Ereignisse in geeignet abstrahierter Form, zu dem Überweiser über.
Das heißt also, das ist so die Benutzbeziehung,
die durch diesen Strom von Ereignissen natürlich vorgegeben wird.
Dann habe ich möglicherweise mal auf den Überweisungsknopf gedrückt,
weil ich vorher so ein paar Zahlen und Daten eingegeben habe,
was ich ja dann interaktiv auch darstellen möchte, ist,
das ist jetzt der neue Kontostand oder ist wohl nicht eine Meldung ausgeben,
dass diese Aktion wahlweise geglückt oder nicht geglückt ist.
Das bedeutet, ich muss von der Art der Beziehung her,
brauche ich jetzt eine Rückkopplung, wieder nach oben und diese Rückkopplung bedeutet,
ich muss von der funktionalen Komponente dem überweise,
brauche ich also einen Kontrollfluss nach oben zur Interaktion,
um sagen zu können, das hat jetzt geklappt,
das hat nicht geklappt, der Kontostand ist jetzt so,
das heißt also, und das wiederum ist so jetzt komme ich genau zu der Stelle,
die ich vorhin gesagt habe,
die wir vermeiden müssen.
Wir brauchen eigentlich so von der Grundidee, brauchen wir eine
zyklische Kopplung zwischen der Interaktion und dem Überweiser. Weil die,
und das brauchen wir für den Moment, also würde ich sagen,
also ich bin absolut überfordert, was bei der technischen Möglichkeiten anbetrifft,
weil das Problem ja einfach von dieser Natur ist.
Es wird was eingegeben, als ist der Strom von Ereignissen
so und es soll was zurückgegeben werden,
also ist der Strom von Ereignissen so, was darauf hinausläuft.
Ich habe eine zyklische Beziehung zwischen den beiden Komponenten,
die ich identifiziert habe, die ich brauche, um diese Aufgabe zu lösen.
Und dieses Rückkopplungsproblem ist eben ein allgemeines Problem. Und dieses
allgemeine Rückkopplungsproblem haben sich also extrem schlaue Leute schon mal angeschaut,
beziehungsweise im Schweiße ihres Angesichts aufgrund schlechter Erfahrungen mit anderen Lösungen.
Haben sich so eine generelle Struktur überlegt, wie dieses Rückkopplungsproblem zu lösen ist.
So, erster Ansatz. Das ist der sogenannte Powling-Ansatz.
Das schreibt man im Übrigen PO-Doppel-L-I-N-G. Wenn Sie das irgendwo sehen,
Sie, wir, also ich rede jetzt mal nur von uns,
Deutsch, Muttersprachlern, ich lese das und sage Polling.
Dann kriegt jeder Engländer, unsere Englischsprachige Sekretärin,
die ist seit Jahren, ist sie darauf geeicht,
wenn ich sage Polling, sagt sie nein, das heißt Polling.
Und ich habe Ihnen das jetzt,
das wird ja auch im Internet aufgezeichnet, das beweiskräftig,
ich habe Ihnen jetzt gesagt, wie man das ausspricht.
Kommen Sie nicht auf die Idee, dass Palling auszusprechen,
das heißt also Poling, was die Interaktion tut.
So, die Interaktion soll also den Überweiser immer wieder fragen
, hat sich etwas geändert
Die soll das also so fragen,
dass sie also immer nachfragt, Entschuldigung,
das war jetzt etwas schnell, weil das soll so aussehen,
wie das aussieht, sage ich Ihnen gleich.
Erstmal kurz das Hilfsmittel, mit dem ich darstelle,
wie das gemacht wird. Ein, das ist das sogenannte UML-Sequenzdiagramm,
dieses UML-Sequenzdiagramm wird dazu verwendet, um die Interaktion zwischen Objekten zu verdeutlichen.
Das läuft also in der Richtung, in der vertikalen sieht man,
welche Objekt, sieht man die Zeit,
ablaufen, in der horizontal,
welche Objekte beteiligt sind
Und das liest sich halt so ein Objekt,
also das erzeugt zu einem etwas späteren Zeitpunkt ein neues Objekt und passiert da irgendwas,
dann läuft der Kontrollfluss wieder zurück zu dem anderen Objekt
und dann kann der Kontrollfluss wiederum etwas anderes tun.
Das ist so ein Darstellungsmittel, um die Interaktion zwischen Objekten darzustellen.
Wenn wir das jetzt mal bei unserem Überweiser anwenden,
dieses Beispiel, ist also folgendes die Interaktion,
sagt also dem Überweiser, die ruft am Überweiser,
der hat ja diese exportierte Operation überweisen,
die Operation rufe ich jetzt mal auf und der Kontrollfluss kehrt
zurück zur Interaktion
So, jetzt war die Lösungsidee eins für das Rückkopplungsproblem.
Ich weiß, ich Interaktion weiß, da muss es jetzt
einen Effekt begeben haben bei dem Überweiser.
Deswegen frage ich mal nach, wie ist denn das Saldo des Auftraggebers?
Und dann bringe ich eine Antwort und dann weiß ich als Interaktion,
das ist also einprogrammiert in die Interaktion,
bei dem Empfänger wird sich wohl auch was verändert haben.
Und dann lasse ich mir das geben und die Saldo-Darstellung wird
dann insgesamt aktualisiert
Dieser Lösungsansatz ist also dadurch charakterisiert,
dass bei der Interaktion Wissen über die Funktionalität vorhanden ist.
Und das soll nicht sein, das soll jetzt nicht so sein.
Es ist eine Entwurfsregel, ich möchte das Wissen über Effekte,
die ich erziele in der Interaktion,
die möchte ich nicht in der Interaktion selbst implementieren,
weil das hat etwas mit Funktionalität zu tun.
Das gehört nicht in die Interaktion. So,
also wenn das nicht die Lösung ist,
dann kommen wir zu Ansatz
Und was wir da machen, ist jedes Mal,
wenn also an der Interaktion etwas, wenn die Interaktion uns den Überweiser aufgerufen hat,
dann rufen wir zurück, so nach dem Motto,
es hat sich was geändert hier in dem Überweiser.
Also muss ich als Überweiser jetzt meiner Interaktion sagen, stell mal den Wert,
der sich hier bei mir im Überweiser verändert hat, stell den mal bitte da.
Das kann man sich so vorstellen, wiederum die Ausgangssituation,
es wird überwiesen und der Überweiser weiß, aha,
der Empfängersaal, der hat sich verändert,
also rufe ich jetzt die Interaktion auf,
stelle erst mal da, aktualisiere den Empfängersaale und als nächstes,
weil dieses Datum hat sich ja auch verändert,
sage ich, aktualisiere mal halt den Auftraggebersaal.
Und das ist also zyklische Verbindung, reinsten Wassers.
Das wollen wir nicht, weil wir ja in der Überweiser-Komponente
keine Annahmen über den Kontext machen wollen,
insbesondere nicht über den interaktiven Kontext.
Also warum sollten wir Kenntnis haben von einer Interaktion?
Und jetzt komme ich zu dem Powling.
Die Grundidee
Die Grundidee versinnbildlicht durch dieses Formalen nicht weiter definierte Symbol ist.
Die Interaktion agiert als Beobachter des Überweisers. Also sie sind
die ständigen Beobachter derjenigen, die sich möglicherweise ändern können.
Von der Idee unserer Vorlesung her, sie brauchen das Gerät
nicht zuklappen. Das ist alles Gute. Ist das jetzt
so, die Vorlesung beginnt. Und zu Beginn der Vorlesung
sagen sie mir, also ich beobachte dich jetzt
Und sie sagen das auch. Und irgendwann haben sie sich
alle bei mir als Beobachter registriert. So, und jetzt
werde ich, laufen sie quasi nebenläufig neben mir her.
Und immer, wenn es ihnen passt, rufen sie mich
mal auf und fragen, hast du dich geändert?
Und sie machen das jede Sekunde. Sie machen das alle
halbe Stunde. Das müssen sie ja wissen. Sie sind ja
meine Beobachter. Ich stelle Ihnen nur die Möglichkeit zur Verfügung,
jede Zustandsänderung, die ich habe, beobachtbar zu machen.
Das ist mein Versprechen. Ich werde nicht klink machen,
ich kann nicht die Mischführung können, was ich sage,
sondern ich mache mich beobachtbar für sie.
Und das ist jetzt so eine Art Vertragsverhältnis zwischen uns.
Sie sind von dem Vertragsparteien her betrachtet.
Sie sind meine Beobachter und ich bin das Beobachtbare Objekt.
In dem Fall, also die Interaktion beobachtet den Überweiser.
Ob und wie sie mich beobachten, ist mir dabei,
Das ist im Großen und Ganzen ist es eine Entscheidung des Beobachters.
Ich verspreche Ihnen einfach nur, wenn ich mich geändert habe,
dann werde ich das zu Ihnen, einen Zugang ermöglichen.
Das ist die Grundidee und die sehen Sie jetzt auch nochmal am Interaktions-,
am Sequenzdiagramm dargestellt. Es wird überweisen, wie immer.
Es wird überwiesen. Und dann klappert in Anführungsstrichen die Interaktion
alle Sondierenden Operationen des Überweisers ab, also ist Überweisung möglich,
wenn das so der Fall ist, sich was geändert?
Also ist der Auftraggeber, ich bin hallo verändert?
Ja, dann frage ich ihn mal ab. Und dann
stelle ich ihn dar. Was macht dann die Interaktion?
Hat sich der Empfängersaal nur verändert? Ja, hat sich
verändert. Dann gib mir doch bitte mal den Empfängersaal.
Und dann wird die Interaktion ihn darstellen. Das heißt,
ich habe jetzt schon eine ziemliche Entkopplung dieser beiden Komponenten voneinander erreicht,
die Funktion, also der Überweiser braucht in keinem Fall mehr,
etwas darüber wissen, also muss jetzt,
muss ich mich, ich überweise,
darum kümmern,
ob das
irgendwo dargestellt werden muss
Dass jemanden interessiert, was sich an mir verändert hat,
dann soll er mich halt fragen.
Und die fragende Komponente ist die Interaktion in unserem Fall und die sagt,
da hatten wir ja verboten,
etwas über den Effekt ihrer Operationen beim Überweiser zu wissen,
die sagt, na gut, dann stelle ich mich halt dumm.
Und das Dummstellen bedeutet, ich werde alle sondierenden Operationen abfragen desjenigen,
den ich beobachte. Und falls sich da etwas geändert hat,
lasse ich mir das Geänderte Datum geben und dann tue ich
das damit, was ich für richtig halte.
In diesem Fall, also es an der Oberfläche darzustellen
Ja. Das kann bei halbwegs realistisch großen Systemen führt,
diese Herangehensweise zu, sagen wir mal, das könnte zu ineffizienzen führen.
Immer alles abfragen und dabei hat sich bloß möglicherweise ein Datum geändert.
Also das ist es nicht. Das ist einfach ineffizient.
Deswegen gibt es eine Weiterentwicklung des Powling-Ansatzes und das sind die,
das ist hier bezeichnet als der Benachrichtigte Beobachter.
Die Idee also In dem Moment,
in dem sich bei dem Beobachtbaren Objekt etwas verändert,
wird es seine Beobachter darüber benachrichtigen,
dass sich eine Zustandsänderung ergeben hat und nachgefragt werden soll.
Für unsere Situation, wenn ich ihr Verhalten zeige,
also hier einfach nur Dann brauche ich Ihnen nicht zu sagen,
dass ich meinen Zustand nicht verändert hat. Ich werde nur,
wenn ich was zu sagen habe, sage ich halt,
es hat sich was geändert und dann sage ich wieder was.
So, also das ist die Grundidee der Benachrichtigte Beobachter,
wird erst in dem Moment nachfragen, wenn der Überweiser gesagt hat,
dass die Beobachtbare Komponente in unserem kleinen Spiel,
wenn sie sagt, ich habe mich geändert.
Das ist so diese,
das wird versinnbildlicht durch diese Glocke
Kommt die Frage, die man, glaube ich,
die letzten zehn Jahre dieser Vorlesung,
da könnte man mal so einen Zusammenschnitt machen,
weil ich das immer frage, wer sagt zu wem,
in welchem Film geben sie ihm ein einzelnes Ping?
Ja, die Jagd auf Roter Oktober,
kein cineastisches Meisterwerk, aber gute Unterhaltung,
soweit ich das beurteilen kann,
das werden immer weniger,
die diese Frage beantworten können
Das ist die Zeit. Muss man in anderen Filmen,
die Jugend heutzutage guckt, wo so ein Satz drin vorkommt.
Wer? Die Matrix ist auch schon so alt, ist auch mal zu sagen.
Die Matrix, dafür bin ich zu alt, ja.
Ich mochte den. Das ist ein anderes Thema. Also,
ein einzelnes Ping soll reichen, um die Interaktion aufzuwecken,
sodass sie die sondierenden Operationen, sodass sie die sondierenden Operationen aufruft.
So, ich habe diese Vorlesung damit angefangen, dass ich
ihnen so schon mal gesagt habe, unseren Kommunikationsverhalten ausschaut.
Ich wollte das jetzt noch mal kurz auf drei Begriffe,
drei Begriffe, die auch in der Softwareentwicklung eine Rolle spielen, zurückbringen.
Das, was ich hier mit Ihnen mache,
ist ein, ich sende einen sogenannten Broadcast.
So, als überzeugter Hörer des Deutschlandfunks kann ich Ihnen sagen,
das ist das Modell des Deutschlandfunks.
Das ist auch mein Modell hier. Ich sende und
ob mir jemand zuhört, ist mir eigentlich egal.
Ich sende jetzt einfach. Und wenn jemand zuhören will,
bitte,
Aber insbesondere kriege ich keine Rückkopplung darüber,
ob mir überhaupt jemand zuhört. Es gibt andere Dozenten,
die stellen zwischendurch Fragen oder so, ob du Fred verteilst Snickers.
Und so, das ist nicht Broadcasting. Mein Stil ist Broadcast,
so ein bisschen geföhnt, da sitzen oder eingeschlafen.
Das ist ein vom Erzeuger an die Umgebung ausgesandtes Signal.
Das nennen wir in der Softwareentwicklung ein Signal. Ich weiß nicht,
wer mir zuhört und ich erwarte, Ich erwarte auch keine Rückkopplung. Demgegenüber,
jetzt gehe ich mal zu dem ersten Element, das,
was wir in gängigen objektorientierten Programmiersprachen als Mittel zur Kommunikation zwischen Komponenten zu,
also Programmierkomponenten zur Verfügung haben, ist der Call.
Und das ist eine viel, viel, das ist die,
das ist eigentlich genau das genaue Gegenteil von, also Beziehungen,
deswegen sage ich es ja auch jetzt hier,
also um das als Gegensatz aufzubauen, zum Broadcast.
Das ist nämlich die Beziehung zwischen einer Komponente und einer
bestimmten anderen Komponente
Es einen Call gibt von dieser Komponente an dieser Komponente,
dann ist es eine starke Bindung, und zwar derart der Kontrollfluss,
kehrt erst dann zurück, wenn die aufgerufene,
die spezifisch aufgerufene Komponente ihre Arbeit erledigt hat,
dann geht der Kontrollfluss an die aufrufende Komponente zurück.
Und in der Zwischenzeit passiert nichts,
das ist jetzt ein bisschen unwissenschaftlich ausgedrückt,
aber hier ist also die konkrete Erwartung,
dass eine bestimmte Dienstleistung erfüllt wird,
also wenn wir über die Benutzbeziehung sprechen,
Und erst dann kann also der Caller wiederum sich mit etwas anderem beschäftigen.
So, dazwischen liegt das Ereignis, das vom Erzeuger oder Verteiler
an einen bestimmten Empfänger weitergeleitet wird. Und das ist das,
was wir jetzt also mit diesem Bild,
das sie da immer noch sehen, also das Ping,
da wird ein Ereignis ausgelöst und dieses Ereignis soll nur diejenigen erreichen,
die sich für dieses Ereignis auch angemeldet haben.
Und das ist eben von der Bindung her,
liegt es genau zwischen dem Broadcast anonym,
ganz viele und also dem Call 1 zu 1,
ist also von der Methodik der Kommunikation her das Ereignis anzusiedeln und so einen Ereignismechanismus,
müssen wir jetzt mit den Mitteln der Programmiersprache Java in unserem Fall, müssen wir den nachbilden.
Und das ist, mir stets nochmal die gängigen objektorientierten Sprachen,
haben weder ein Ereignis noch einen Signalmechanismus,
also und das wird zwar jetzt,
also langsam aber sicher wird es so mainstream,
also ich glaube in C-Shart gibt es mittlerweile auch so ein Ereignismechanismus.
Ich gucke mal, während ich spreche,
so zu dir ist
Eins, die ich habe, gab es den schon immer.
Das ist ungefähr so, wie die Hand, The Hunt for Red Oktober.
Also das ist eine neuere Programmiersprache. So, und jetzt kommen wir dazu,
wie wird der Ereignismechanismus in einer Programmiersprache wie Java,
die den nicht natürlicherweise mitbringt, wie wird der dort implementiert?
Und wir bringen ihnen jetzt dieses Konzept, also auch deswegen bei,
weil also diese Form der Kopplung oder Entkopplung vielmehr ist,
sagt eigentlich dasselbe aus.
Das ist nur eine Frage der Betonung. Also wie,
dass diese Form von Entkopplung kann an sehr vielen verschiedenen Stellen kann die eingesetzt werden.
Also nicht nur, um zum Beispiel so das Thema,
das Thema, das wir jetzt behandeln,
nämlich die Entkopplung von Funktionalität und Interaktion zu betreiben,
sondern auch an anderen Stellen.
Also wo, also diese 1-zu-N-Beziehung zwischen einem beobachtbaren und mehreren Beobachtern eine Rolle spielt.
Okay, wer sind jetzt die Mitspieler in diesem Kontext von Beobachtung?
Da gibt es zwei. Das macht die Sache ja
schon mal überschaubar. Es gibt also ein Interface,
das heißt Beobachter, Und dieses Interface soll eine Operation,
muss eine Operation enthalten, nämlich beachte Änderung.
Dann gibt es einen, der ist beobachtbar und was der hat,
ist, also man kann sich bei ihm registrieren über die Operation,
Sätze, Beobachter.
Und dass man da als Parameter übergibt, ist ein Beobachter.
Falls sich das beobachtbare Objekt verändert, wird es bei sich,
die Operation, melde Änderungen aufrufen.
Und das führt dazu, dass alle Beobachter mit der von
ihnen implementierten Operation beachte Änderungen aufgerufen werden.
So einfach kann das sein. Schon habe ich
das Rückkopplungsproblem gelöst
Ich nehme jetzt mal jemand anders,
wenn ich sie einladen darf, mich zu beobachten.
Ich bin der beobachtbare Guido und sie sind die beobachtende Studierende.
Was sie bei mir aufrufen können, ist jetzt,
was warum über Sätze beobachte, es macht jetzt gerade ein bisschen schwierig hier.
Kenny Folien zu einem Wesentlichen auswendig. Da ich weiß,
dass sie jetzt eine Beobachterin sind, weiß ich,
ich kann bei ihnen die Operation beachte Änderung aufrufen
Und jedes Mal, wenn ich also eine Änderung zu melden habe,
dann sage ich jetzt all meinen Beobachtern,
also über meine Operation, melde, Änderung, beachte Änderung.
Und das ist dann ihre Chance, also bei mir die sondierenden Operationen,
was hat er jetzt schon wieder gesagt, aufzurufen.
Und dann sind wir miteinander verknüpft. Und das machen wir
jetzt also mit allen 150 Leuten, die hier sind.
Und so können sie mich beobachten.
Das gucken wir uns jetzt nochmal im Zusammenspiel an.
Erstmal, wer sind die Beteiligten Mitspieler jetzt im Kontext
des Überweisers
Der Überweiser selbst ist die beobachtbare Komponente. Jedes Mal,
wenn der sich ändert, wird er also melde Änderungen aufrufen
und bei all seinen registrierten Beobachtern wird beachte Änderungen aufrufen.
Und die Interaktion ist eine Beobachtende Klasse. Die muss also
das Interface beobachten implementieren und ihre Implementation von beachte Änderungen führt dazu,
dass sie bei dem beobachtbaren Objekt,
bei dem sie sich angemeldet hat,
sich den Zustand geben lässt und dann eben
diesen Zustand zeigt
So, und das ist jetzt so diese Art von Struktur.
Das ist also jetzt ein Muster, über das sie jetzt,
das gehört ab jetzt zu ihrem Repertoire von Wissen,
wie man Probleme, wiederkehrende Probleme in einem Kontext lösen kann.
Dieses Muster ist das Beobachtermuster. Und das sieht im Großen
und Ganzen, sieht das immer so aus.
Also die Mitspieler sind bekannt, das Interface-Beobachter, die Klasse beobachtbar.
Es ist darüber hinaus festgelegt, wie diese beiden Mitspieler miteinander
zusammenhängen und wie in den Kontext eines Problems eingefasst werden sollen.
In diesem Fall, in dem also die Klasse über Weiser
erbt von der Klasse, beobachte und die Interaktion implementiertes Interface beobachter.
Das Beobachtermuster ist eins von 23, ich komme da gleich noch drauf.
Zunächst müssen wir uns kurz anschauen, nochmal im Interaktion Sequenzdiagramm,
wie denn jetzt eigentlich so die Verknüpfung zwischen einer Beobachtenden und einer beobachtbaren Komponente,
wie diese Interaktion zustande komme.
Das lasse ich mir dann auch jedes Semester nicht nehmen,
meine Begeisterung über, wie spricht man das, was hier passiert.
Also die Klasse über Weiser ist ja zur Laufzeit,
also das Objekt über Weiser, stellt ja eine Operation,
Sätze, Beobachter zur Verfügung.
Wie wird die jetzt von der Interaktion aufgerufen?
Nun, Sätze, Beobachter, so viel ist klar.
Und dieses Stück Code hier übersetzt, da kann man sprechend sagen,
Ich über Ich-Interaktion übergebe mich als Parameter.
Das sage ich jedes Jahr gerne. Ich übergebe mich hier
als Parameter. Weil ich möchte ja mich als Beobachter registrieren.
Deswegen muss ich mich geschrieben als This,
muss ich halt als Parameter der Operationssätze beobachten, mitgeben.
Und das ist ja klasse, oder?
Jetzt fängt Objektorientierung noch wirklich an Spaß zu machen
Ja, wenn man sagen kann, naja,
wenn ich also bei dem überweise, einen Beobachter registrieren möchte,
dann muss ich ihm schon sagen, wer denn dieser Beobachter sein soll.
Und in dem Fall bin ich das halt,
den ich hier beim Überweiser als Beobachter eintrage.
Weil jetzt sind natürlich dem so, in Kenntnis dieser Konstruktion
können Sie jetzt natürlich lustige Sachen machen. Sie wissen,
dass Sie mich beobachten wollen, also übergeben Sie sich an mich.
Okay. Gleichzeitig sagen Sie aber auch,
ich spiele jetzt mal in meinem Kommilitoneneinstreich übergebe ich jetzt auch
noch als Beobachter, ohne dass der was davon weiß.
Und schon kriegt er von mir Änderungsmeldungen und weiß gar nicht,
wie ihm geschehen ist. Jetzt sind wir eine Stufe höher.
Sie kennen also jetzt die Vorteile dieses, die Vorteile dieses Mechanismus.
Und jetzt fangen wir an mal mit diesem Mechanismus zu spielen.
Also erste Frage ist, soll es in diesem Fall möglich sein
oder macht es Sinn, jemand anders als Beobachter zu übergeben?
Warum? Ich will es nicht ausschließen. Für den Kontext,
in dem wir uns jetzt bewegen, denke ich,
macht das eher wenig Sinn. Eine andere Frage,
die sich stellt, ist, Jetzt haben Sie...
Machen wir mal zu den nächsten Sequenzdiagrammen über,
wie geht es so in der Dynamik?
Okay, also überweisen. Gut. Dann passiert was im Überweiser.
Der kriegt jetzt also, jetzt geht dieser Rückkopplungsmechanismus los. Er ruft an sich selbst,
meldet Änderungen auf und das läuft darauf hinaus, dass er aus,
in der von ihm geerbten Klasse beobachtbar, dass er die Operation beachte,
Änderungen aufruft und jetzt muss in den Beobachtenden Objekten,
muss jetzt halt das passieren, was passieren soll,
wenn man auf eine Meldungsänderung antworten möchte,
die ganzen sondierenden Operationen werden abgefragt.
Und jetzt sage ich, und dann guckt man halt,
also muss ich jetzt tatsächlich, muss ich mich jetzt,
muss ich irgendwas in der Interaktion, muss irgendwas aktualisiert dargestellt werden.
Die nächste Frage, die sich jetzt stellt, ist,
ich bleibe jetzt bei Ihnen, Sie haben sich schon dran gewöhnt.
Setzen Sie sich im nächsten Mal einfach da oben hin, okay?
Ich sage Ihnen jetzt, ich habe mich geändert.
Ich rufe an mir Meldeänderung auf und an Ihnen
rufe ich jetzt beachte Änderungen auf
Hindert sie jetzt niemand daran, meinen Zustand zu verändern.
Sie haben ja schließlich den Kontrollfluss bei Ihnen jetzt.
Und jetzt könnten Sie glatt nochmal sagen, ach,
weißt du was, überweis mal nochmal 100 Euro.
Und dann mache ich das, weil schließlich ist der Kontrollfluss
ja bei Ihnen. Und dann sage ich, melde Änderung,
beachte Änderung mit der Kontrollfluss, ist wieder bei Ihnen.
Die anderen Beobachter haben keine Chance mehr,
mich in dem Zustand zu beobachten, den ich ursprünglich hatte,
als ich das erste melde, Änderung gemeldet habe.
Und das Das ist seine Schuld. Ganz alleine.
Wo ich schon von Schurken sprach. Beruhigen Sie sich.
Ich habe ein ganz kurzes Gedächtnis. Also nach der Veranstaltung
sind sie weg. Was lernen wir jetzt daraus? Das
Verhältnis zwischen beobachtbaren und beobachtenden Objekten ist also durchaus auch fragil.
Während eines durchlaufs von Melde bzw. beachte Änderung dürfen die Beobachtenden
Objekte, das Beobachtbare Objekt nicht verändern
Einfach aus Fairness gegenüber den anderen, dem einzelnen Beobachter,
unbekannten anderen Beobachtern. Und das alles nur,
weil es kein, also implementierten Ereignismechanismus gibt,
der sicherstellt, dass alle gleichzeitig über diese Informationen verfügen.
Naja, man tut was, man kann mit dem,
was man hat. Und solange man sich in einem,
also singulären Prozessraum bewegt,
ist das Beobachtermuster ist schon
ein gutes Stück
Software-Engineering ist jetzt vielleicht auch ein bisschen hochtragend formuliert,
aber sie sehen möglicherweise, also da steckt jetzt eine Menge Erfahrungswissen,
also ja, da steckt eine Menge Erfahrungswissen dahinter.
Also dann mal zu sagen, ich habe hier einen,
zwar ein konkretes Problem gelöst,
aber da steckt eine allgemeine Struktur dahinter,
die möglicherweise auch an anderen Stellen sinnvoll eingesetzt werden kann.
Und das ist das Grundprinzip der Entwurfsmuster
Jetzt hier im besonderen Fall, also das Beobachtermuster,
das für sie aufbereitet. So ist das von GHJV,
das steht für Gamma Helms, Johnson Flecidis, die also das kommt,
am Ende zeige ich auch nochmal die volle Literaturreferenz, die also,
glaube ich, das meistverkaufte Buch der Softwaretechnik überhaupt geschrieben haben,
nämlich das Buch Design Patterns.
Da sind, also da ist diese klassische Sammlung von Entwurfsmus
dann drin enthalten. So. Entwurfsmuster selbst werden Musterartig beschrieben.
Jedes Entwurfsmuster hat also die Er hat erstmal einen Namen.
Wir haben gerade das Beobachtermuster kennengelernt. Es gibt ein Problem,
das mit Hilfe dieses Musters gelöst werden soll.
Und die Leser dieses Musterkataloges brauchen also ein gewisses Erfahrungswissen,
um das Problem als solches verstehen zu können.
Weil was nützt es mir, wenn hier also eine Lösung
vorgeschlagen wird für ein Problem, das ich nicht habe.
Heute sich noch nicht als solches erkannt habe. Es braucht ein gewisses Erfahrungswissen,
um ein Problem als solches erkennen zu können,
um dann so zu verstehen, wie sieht also die Lösung aus,
mit der dieses Problem in seinem Kontext gelöst werden kann.
Ja, und wir haben jetzt schon auch so ein paar Elemente der Lösung und seine,
also wie sie konstruiert werden kann, haben wir hier auch schon gesehen.
Es ist bei jeder Beschreibung eines Entwurfsmusters ist klar,
welche Klassen werden gebraucht, in welchem Zusammenspiel,
um eine Lösung für dieses Problem darzustellen.
Und dann gibt es eben noch Konsequenzen,
also bei jeder Lösung gibt es so ein Problem gelöst und also möglicherweise andere Probleme werden geschaffen,
die hoffentlich in der Summe etwas kleiner sind.
Also das Problem, das gelöst wird.
Jetzt sind wir schon so im Allgemeineren etwas abstrakteren Fahrwasser.
Zeig jetzt gleich mal noch so ein paar von den
ein paar Entwurfsmuster und wie sie selbst nochmal unterteilt werden.
Einen Punkt können wir hier an der Stelle aber noch machen.
Der heißt, wir haben jetzt, also wir zusammen,
haben jetzt dieses Problem verstanden,
eins zu N-Beziehung und wie löse ich es,
ohne dass ich eine zyklische Benutztbeziehung zwischen Klassen etabliere
Das haben wir uns jetzt angeschaut. Und jetzt haben wir
uns einen Konstruktionsansatz auch angeschaut, mit dem wir dieses Problem lösen können.
Und dieser Konstruktionsansatz bestimmt da sind,
dass wir so eine Liste von Beobachtern genommen haben und diese Liste wird stumpf,
wenn ich so sagen darf, wird sie für jede Änderung, wird sie durchgeführt.
Und jetzt kann man anfangen, sich andere Konstruktionsansätze für dieses Prinzip,
für dieses Prinzip, das benachrichtigten Beobachters zu überlegen.
Und sich zum Beispiel überlegen,
melde mich nicht generell bei einer Beobachtbaren Komponente für alle Änderungen,
die sie von sich gibt, an,
sondern ich melde mich für bestimmte Ereignisse an,
von denen ich als Beobachter sage, also es interessiert mich.
Dann melden Sie sich eben nur an,
wenn ich darüber spreche, Achtung, Klausurrelevantes Wissen.
Nur dann, alles andere weg.
Man ist ja effizient
So ein Ereignis müsste ich natürlich anbieten.
Einen Teufel werde ich tun. Weil ich sage nur,
es ist alles für ihr Leben als Softwareentwickler,
von entscheidender Bedeutung, was ich hier von mir gebe.
So, Nutzen von Entwurfsmustern. Ja, Sie haben noch
dieses Bild vor Augen, das ich ganz am Anfang gezeigt habe.
Wir möchten, wir Softwareentwicklern. Das, was uns mit Soft,
mit Entwurfsmustern gelingen soll, ist, das Sprechen über Entwürfe.
Die Kommunikation darüber, was Sie im Kopf haben und wie Sie es realisieren, dass das auf eine höhere Abstraktionsebene, auf eine verdichtetere Kommunikationsebene gestellt wird. Wir brauchen uns nur das Problem,
dass das mit dem Beobachtermuster gelöst wird, noch mal kurz anschauen,
weil wenn Sie das jemandem erklären wollen, was Sie da getan haben,
und Sie verfügen nicht über das Vokabular, Beobachter musste,
dann müssen Sie anfangen, ja, weißt du,
ich habe hier eine Klasse, die,
also da kann man sich registrieren und wenn sich was ändert,
dann muss also die andere Klasse,
die muss dieses Interface implementieren und das rufe ich dann auf und ach komm,
ich zeichne dir das mal auf,
komm,
wir gucken uns das mal eben im Code an
So, das ist jetzt vorbei, diese Geschichte.
Jetzt sagen Sie, ich habe das Beobachter und Muster verwendet,
um diese Abhängigkeit zu implementieren, sagt ihr Kommilitone, alles klar.
Oder? Das war die richtige Reaktion. Und jetzt gibt
es also für eine ganze Reihe von Problemen auf einer,
die heißen deswegen ja auch Mikroarchitekturen, für eine ganze Reihe von Problemen,
gibt es diese vorgefertigten Lösungen, sodass sie sagen können,
Ja, dafür habe ich das Beobachtermuster verwendet.
Dafür habe ich das Proxy verwendet. Dafür habe ich einen Adapter verwendet.
Dafür habe ich eine Strategy, dafür habe ich eine Fabrik.
Ein paar werden wir noch kennenlernen. Und dann ist allen Beteiligten klar,
oh ja, das sind Strukturen, die ich kenne. Und jemand,
der diese Strukturen verwendet, zeigt auch gleichzeitig,
der hat also sein bisschen Software-Engineering-Handwerk,
hat er gelernt und alle Beteiligten können viel effizienter miteinander kommunizieren,
ganz zu schweigen davon, dass man dem Code auch,
also man sieht es ihn nicht, an,
aber man kann in den Code Strukturen hinein interpretieren,
die in leichter verständlich machen.
So, da sind sie jetzt. Die, also Alexander 233 musste,
Gamma, Helms, Johnson Vliceidis, das sind also vier Softwareentwickler,
die werden kurz auch als Gang of 4 bezeichnet.
Ja, das ist zwar nicht so nett,
aber Gang of 4 wird dann auch als Goff zitiert,
also wenn sie das irgendwo in einem Artikel lesen oder in einem Buch,
das also Goff haben gesagt, das, dann müssen Sie ab heute auch Bescheid.
Aha, das ist die Gang of 4 und es sind diese vier Herren,
das Cover des Buches zeige ich gleich noch.
Die haben ursprünglich diesen Musterkatalog herausgebracht. So, die 23 Muster,
will ich jetzt nur mal kurz bezüglich ihrer Aufgaben erzeugen.
Sie dachten, Objekterzeugung, kein Problem, schreibe ich New,
dann habe ich das getan. Es gibt jetzt verschiedene Probleme,
die eine etwas größere Abstraktion, Trennung, Entkopplung zwischen demjenigen,
der ein Objekt haben möchte und demjenigen, der dieses Objekt erzeugt,
die einigen Probleme, die eine etwas größere Trennung erfordern.
Und da nun mal so beispielhaft ist also die abstrakte Fabrik,
ist dazu ein Muster, das verwendet werden kann.
Das Problem, das ich habe, ist, oder sich lösen will,
ist, ich möchte den konkreten Typ eines Objektes,
das ich verwende, nicht kennen.
Ich möchte nur sagen können, ich möchte etwas haben,
worauf ich über es überweisen kann.
Und das sage ich einer abstrakten Fabrik.
Und die liefert mir dann etwas, was so überweisen kann.
Dann programmiere ich nur noch gegen dieses Interface,
ohne dass ich den konkreten Typ kenne. Das heißt,
ich habe wieder ein Stück Abstraktion in meinem Code,
unabhängig von Unabhängigkeit, von einer konkreten Implementation hinein implementiert.
Wenn das ihr Problem ist, dann schauen Sie sich
das Entwurfsmuster abstrakte Fabrik an
So, das sind,
es gibt da jetzt eine Reihe von sogenannten Erzeugungsmuster und dem Gegenüber
werden auch noch sogenannte Struktur und Verhaltensmuster werden unterschieden.
Mal so kurz der Adapter. Es ist etwas,
gerade die Mac-User unter uns, also gehen ja nie aus dem Haus,
ohne, also mindestens zwei Adapter dabei zu haben.
Wie kann eine Struktur, die mit einer anderen verbunden werden soll,
obwohl diese beiden nicht dazu geschaffen sind,
also unmittelbar miteinander zu arbeiten,
wie kann das trotzdem passieren
Dazu gibt es das Entwurfsmuster Adapter. Das ist ein sogenanntes Strukturmuster,
weil es die Strukturellen, so Unterschiede versucht auszugleichen.
Da war jetzt eine Frage. Super, hat sich geklärt.
Weitere, die werden wir so gerade so in Softwaretechnik werden,
wenn noch so verschiedene andere Muster kennenlernen. Eins haben sie schon kennengelernt,
die Schablonenmethode, also das Programmieren von Methoden ohne,
also die konkrete Implementation anderer Methoden bekannt sind und dazu die Verwendung von Oberklassen,
ist auch eins der Muster, die von Gamma und anderen in den Kanon aufgenommen worden ist.
So, so interessant. So, da sind sie nochmal.
Design-Patterns, das ist 1995, ist das implementiert worden.
Ist das also geschrieben worden? So Grundlage für dieses Buch war die Dissertation,
das ist nicht die Grundlage, aber eine der Grundlagen dieses Buches war,
also die Dissertation von Erich Gamma,
wo er ursprünglich das Konzept der Entwurfsmuster veröffentlicht hat und die Grundlage für,
soweit wie mir die Geschichte bekannt ist,
die Grundlage dafür war folgendes.
Die Leute haben eine Programmierumgebung entwickelt und sie haben diese Programmierumgebung geschrieben,
glaube ich, unter Unix und dafür haben sie die Unix-Grafik-Grafik-Komponenten verwendet.
Irgendwas, was mit C daherkommt. Dann haben sie
das portiert in eine damals, glaube ich, Windows-Umgebung.
Was sie dann festgestellt haben, ist,
dass sie ganz schön viel Code der eigentlichen Programmierumgebung überhaupt nichts
zu tun hatte mit dem, was die Programmierumgebung eigentlich tun soll.
Das ist das Reimplementieren mussten. Und dann haben sie es
noch auf dem Mac, also portiert und wieder mussten,
also fast alles neu implementiert werden. Und dann haben sie so,
ich habe vorhin davon gesprochen, im Schweiße ihres Angesichts sagte,
wir müssen mal die Funktionalität der Programmierumgebung von ihrer grafischen Repräsentation trennen.
Und dann haben sie das Beobachtenmuster erfunden. Also das Erfinden
von Entwurfsmustern ist also nicht etwas, wo sich berühmte Wissenschaftler
mal so für drei Monate in ihren Keller zurückziehen und mal scharf nachdenken.
Und das ist das Ergebnis von harter, schmerzhafte Programmiererfahrung.
Warum muss ich dieses Problem immer wieder lösen? Dass ich habe,
was meine Arbeitszeit kostet, was fehlerhaft ist,
worüber ich mich mit niemandem unterhalten kann.
Und dann kommen die Leute auf die Idee, Entwurfsmuster zu entwickeln.
Und das hat jetzt diese, die haben die ganze Diskussion losgetreten,
ein bisschen, hat einen falschen Zungenschlag.
Also die haben diese Diskussion über die Jungs haben,
die Herren haben diese Diskussion über Entwurfsmuster begründet.
Und es gibt mittlerweile ganze Konferenzkreihen, die sich mit Entwurfsmustern
beschäftigen, welche Entwurfsmuster hilfreich sinnvoll sind. Also Entwurfsmuster,
wir haben die ja jetzt hier nur kennengelernt zur Programmierung im Kleinen auf der Ebene von Mikroarchitekturen.
Und die ganze Diskussion über Entwurfsmuster ist jetzt auch weiter.
Also bis hin zu Mustern für Unternehmensarchitekturen. Die Idee der
Muster kommt ja ursprünglich aus der Architektur, wird jetzt also einfach in Anführungsstrichen,
wird jeweils dahingehend überprüft, ob die nicht auch übertragbar ist, denn andere Anwendungsgebiete. Und dass da,
das Buch gibt es auch, ich weiß nicht,
in wie vielfacher Ausfertigung auch in elektronischer Form in der Bibliothek,
das gehört also bestimmt eine Zeit ein bisschen,
die mussten alle auswendig kennen, gehört es zu ihrem täglichen Brot,
da ab und zu mal reinzublättern und zu schauen,
für welche Probleme die Leute,
die diese Muster aufgeschrieben haben,
schon Lösungen gefunden haben
Ich kehre ein in die Zusammenfassung. Ich hoffe,
ich konnte so eine kleine Idee davon vermitteln.
Das Entwurfsmuster, so für die Strukturierung von Code,
für die Erhöhung von Qualität, dass sie einen Beitrag leisten können.
Hier steht auch zum Softwaretechnischen Handwerkszeug, da stehen wir zu,
gehört die Kenntnis über diese verschiedenen Arten von Mustern,
die ich am Schluss nochmal so unterteilt habe, also Erzeugungsstruktur und Verhaltensmuster.
Und das kann man auch nicht häufig genug sagen.
Also das eine, worüber sie verfügen,
sind so die Beherrschung von den Mitteln einer objektorientierten Programmiersprache.
Und das andere ist so, da werden sie, werden wir noch hinkommen.
Also nur wenig in diesem Semester, in den kommenden Semestern,
ein Entwurfsmuster, ein Bestandteil bei der Strukturierung großer Softwaresysteme bezüglich ihrer Architektur.
Und die Entwurfsmusterdiskussion hat da so etwas von,
das Missing Link, das jahrelang, also dazu geführt hat,
dass also immer größere Systeme, die immer schlechter strukturiert gewesen sind,
erstellt worden sind.
Entwurstmuster sind da so ein bisschen wie das Missing Link.
Und mit diesen Aussagen werde ich sie heute ins lange Pfingstwochenende
und in die Pfingstferie entlassen, nicht wahr?
Nächsten Mittwoch bist du bis weder du noch ich da.
Sie brauchen uns dann auch nicht zu beobachten.
Es gibt nichts zu beobachten, nächsten Mittwoch hier.
Und übernächsten Mittwoch bist du dann wieder hier.
Und mich sehen sie dann, also auch übernächsten,
aber an dieser Stelle in drei Wochen wieder.
Das ist ja
fast schon wieder Semesterende,
Meine Güte, er ist time goes by. Also,
ich gebe Ihnen ein einzelnes Ping mit auf den Weg
und wünsche ansonsten frohe Pfingsten.
Auf Wiederhören