So, meine Damen und Herren. Schönen guten Tag.
Heute reden wir, könnten Sie vielleicht noch die Tür zuziehen?
Danke. Heute reden wir über Mikroarchitekturen in objektorientierter Software.
Das ist so ein bisschen angelehnt an den Architekturbegriff,
den Architekten verwenden
Ja, ist so eine Art von, also ich rede jetzt
nur von mir, so eine Art von Transdisziplinärer Herangehensweise.
Also Softwareentwickler müssen ja ständig versuchen, jemandem,
also entweder unter uns oder anderen zu erklären,
was macht ihr eigentlich den ganzen Tag?
Und eins der Probleme, das wir haben,
ist ja, wir können das, was wir tun,
so unglaublich schlecht, also kommunizieren, geschweige denn visualisieren.
Da haben es die Leute, die sich mit richtigen Architekturen beschäftigen,
also sowas oder sowas, die haben es ja echt einfacher.
Da guckt man drauf und denkt, Ist das richtig?
Ist das falsch? Also da haben wir,
wir haben eine sinnliche, einen sinnlichen Zugang zu schlechter Architektur.
Oder Pfusch am Bau. Und das,
das geht ja eben so die ähnliche Richtung hier, oder?
Was ist da passiert? Das ist gefährlicher als das andere,
oder? Da guckt man jetzt einmal drauf und jeder erkennt jeder von uns,
erkennt sofort, Das ist, also das kann,
das kann es nicht sein oder das kann es nicht gewesen sein oder so.
Das ist so diese Art von Renovierung, die hier stattgefunden hat.
So, ich glaube, die Nachricht ist jetzt bei Ihnen angekommen.
Jetzt kann ich zu den anderen Folien wechseln.
Jetzt komme ich nämlich zu uns. Jetzt gucken Sie
hier drauf
Was sagt Ihnen, die ihre sinnliche Wahrnehmung zu diesem,
ja was ist das überhaupt? Das sind jede Menge Klassen,
also Java-Klassen, da wird gezeigt, so in welchen Beziehungen,
die zueinander stehen, so in welcher Benutztbeziehung, die zueinander stehen.
Da guckt man jetzt drauf und denkt,
ja ist es jetzt gut oder ist es schlecht oder was?
Man weiß es ja nicht. Und das,
was Sie jetzt im Laufe Ihres Studiums lernen werden,
also was Sie da sehen, ist problematisch.
Also das müssen Sie jetzt noch nicht,
Wir versuchen ihnen so, was wir versuchen, ihnen beizubringen,
ist, dass es auch für große Software-Systeme,
dass es da auch so architektonische Regeln gibt,
nach denen wir die, also entwerfen und bewerten können.
Und was sie da sehen, ist also ein sogenannter,
also es gibt so jede Menge schlechte Gerüche,
die so Software-Systeme metaphorisch gesprochen, annehmen können.
Und der schlechte Geruch, der hier sichtbar wird,
ist die sogenannte Gottklasse.
Das sind sogar zwei davon, sehen das hier so
in der Beurteilung
Also was so eine Gottklasse ausmacht. Und das sind so
Zeichen für ein Überarbeitungswürdigen, Entwurf, beziehungsweise soweit sollte man
es gar nicht erst kommen lassen, aber Dinge passieren.
Und wenn man dann so ein Stück Software vor sich sieht,
dann weiß man, also ach,
da gibt es jetzt, also man kann das wegschmeißen,
man kann es neu bauen und muss es renovieren.
Je nachdem, wozu man bereit ist, wozu man in der Lage ist.
So, und jetzt haben sie Was kennen Sie denn jetzt
so an Gestaltungsmitteln für Softwaresysteme? Sie kennen Klassen, Sie wissen,
wie Klassen in Beziehungen zueinandergesetzt werden können, benutzt Beziehungen für Erbungsbeziehungen.
Sie haben ein Strukturierungsmittel, haben Sie Pakete kennengelernt,
wir werden so, werden noch ein paar andere,
also auch nicht mehr sprachliche Mittel, aber konzeptionelle Mittel kennenlernen.
Dann ist die Frage, so wie sprechen Sie über Entwürfe?
Wie können Sie untereinander auch? Also sich versuchen klar zu machen,
was tue ich denn da jetzt gerade? Also wenn ich so zwei,
drei, vier, 500 Klassen, so wenn ich ein Problem löse,
Haben Sie noch eine Sprachebene darüber,
also mit der Sie die grundsätzliche Idee erläutern können,
wie Sie jetzt gerade ein Problem, das Sie haben,
gelöst bekommen?
Können Sie nicht. Nach dieser Vorlesung können Sie das.
So, das ist jetzt ein toller Spannungsbogen, oder? Das,
was uns, das, was Sie dafür brauchen,
sind sogenannte Mikroarchitekturen, Entwurfsmuster, die Ihnen helfen,
Einen immer wiederkehrendes Problem in einem bestimmten Kontext auf immer die gleiche Art und Weise zu lösen.
Das sind Mikroarchitekturen. Und das ist eben angelehnt an Mikroarchitekturen
an diesem Begriff des Entwurfsmusters von einem Architekten namens Christopher Alexander.
Also wohl in der Architekten-Szene, da ich wie gesagt,
ich kenne mich da überhaupt nicht aus, ein ziemlich berühmter,
ziemlich berühmter Mensch,
sehr viel veröffentlicht.
Das ist auch
viel diskutiert
Währenddessen arbeiten über Mikroarchitekturen, über Muster. Das haben also Softwareentwickler,
haben das so rezipiert und so für die Softwareentwicklung nutzbar gemacht.
Und das, was wir daraus gemacht haben, wir,
also nicht ich, also wir, die Softwaretechniker,
wir haben also den Begriff des Entwurfsmusters geprägt und einen Entwurfsmuster.
Wir sehen hier die Definition, beschreibt abstrakt eine bewährte Lösung,
also das ist für ein bestimmtes und häufig wiederkehrendes Problem
Also das ist so die Grundidee. Leute, die lange
Software entwickeln, kriegen irgendwann so, kriegen sie mit.
Mensch, das Problem habe ich doch schon mal gehabt.
Da habe ich auch schon mal gelöst.
Wie war denn das? Aha, so weit er ist.
Oder man redet mit jemandem und sagt, du,
ich habe da ein bestimmtes Problem.
Hast du das schon mal gehabt? Hast du es schon
mal gesehen, dieses Problem? Und dann sagt er,
ja, das hört sich so an wie.
Und jetzt geht es darum, also diese grundsätzliche Idee,
wie man ein bestimmtes wiederkehrendes Problem lösen kann,
dieses Problem zu benennen
Zu sagen, ach, guck mal, ich nenne dieses Problem
jetzt mal und jetzt komme ich gleich zu dem ersten Beispiel.
Ich nenne dieses Problem mal,
oder ich beschreibe dieses Problem erst mal so, eine 1-zu-N-Beziehung zwischen,
es ist jetzt ein Beispiel für so ein Problem,
eine 1-zu-N-Beziehung zwischen Objekten, sodass die Änderung des Zustands eines Objekts dazu führt,
dass alle abhängigen Objekte benachrichtigt und automatisch aktualisiert werden.
Auf so ein Problem muss man ja erst mal kommen, oder?
Das denkt man sich nicht aus, so ein Problem.
So ein Problem hat man
Und dann weiß man das, dass man dieses Problem hat.
Also so ist jetzt nochmal so, sagen,
so formulieren darf. Also wir, ich zu Ihnen,
stehe jetzt gerade so in einer 1-zu-N-Beziehung.
Also ich ändere meinen Zustand und dann möchte ich,
dass Sie das mitbekommen, sodass ich etwas sage.
Das ist jetzt so die Art und Weise,
wie wir miteinander reden, ist nicht besonders so objektorientiert,
ist halt eher menschlich.
Aber jetzt stellen Sie sich mal vor,
ich wäre ein Objekt. Und Sie wären auch Objekte.
Jetzt komme ich mal zu Ihnen
Ich sage jetzt was und dann möchte ich,
dass sie das hören, dass sie das mitkriegen.
Also sage ich Ihnen das, ich sage einfach erst mal,
ich habe mich geändert und dann möchte ich,
dass sie diese Änderung bei mir abfragen.
Jetzt tun Sie das. Da wir uns ja in einem synchronen Prozessraum bewegen,
kommt der Kontrollfluss also wieder zu mir zurück und dann sage ich Ihnen,
dass ich mich geändert habe.
Und dann frage sie nach, was sich geändert hat.
Kriegen Sie diese Änderung mit? Und dann komme ich
zu Ihnen und zu Ihnen komme ich auch noch.
Das mache ich jetzt mit allen paar hundert Leuten,
also viel sind Sie nicht mehr,
mache ich das so hintereinander weg
Ein Objekt ändert seinen Zustand und möchte, dass alle anderen abhängigen Objekte das mitbekommen.
Dieses Problem hat man mitunter. Bei der Entwicklung,
Objekt auch nicht nur bei der Entwicklung, objektorientierter Software,
aber auch da. Vor allem, wenn es nachher darum geht,
ich werde es ja jetzt in den Übungen,
wird es jetzt so langsam kommen, wenn es darum geht,
sich mit reaktiven Oberflächen zu beschäftigen.
Da hat man genau dieses Problem. Das heißt also,
um das mal so nicht dass sie da jetzt so die Vorstellung entwickeln.
Sie könnten sich da jetzt hinsetzen und sich Entwurfsmuster überlegen,
lassen sie das. Vergessen sie das einfach.
Programmieren sie einfach. Und dann werden sie merken,
dass sie Probleme haben. Und dann können sie anfangen,
sich mal mit so Mustersammlungen auseinanderzusetzen und gucken,
ob das Problem, das sie gerade haben,
ob das vielleicht schon mal jemand gelöst hat.
Und wie das so grundsätzlich geht,
das zeige ich Ihnen jetzt mal an einem Beispiel.
Schauen Sie sich mal
diese Schnittstelle an
Wir wollen sowas wie ein Überweiser implementieren, also so ein Stück Software,
mit dem man einen Geldbetrag von einem Auftraggeberkonto auf einen Auftragnehmerkonto überweisen kann.
Und da gibt es halt so eine Schnittstelle,
und die heißt also, man kann ja irgendwelche Daten setzen,
man kann diese Operation hier aufrufen und dann wird was überwiesen.
So, man kann sich was anzeigen lassen,
also Werte liefern lassen,
also wie viel ist denn auf dem Empfängerkonto drauf,
wie viel ist auf dem Auftraggeberkonto drauf und so weiter.
So,
es gibt ein paar sondierende Operationen
Das ist so die Schnittstelle, die macht ja jetzt überhaupt keine Annahme darüber.
Also wie sieht das eigentlich an der Oberfläche aus?
Wissen wir einfach nicht. Wir wissen nur, dass hier so die Funktionalität,
dieses Überweisers, das ist ja auch erstmal gut genug. So,
sehen Sie doch, das sehen Sie hier nochmal,
welche Arten von Operationen wir unterscheiden, verändernde Operationen,
also der Zustand des Objektes wird dann ein anderer sein nach Aufruf dieser Operation,
Sondierende, Operation kann ich es häufig aufrufen, wie ich möchte.
Das werden Informationen abgefragt und also bulsche Operationen, Prädikate,
also mit sowas wie Parameter überprüft werden können oder Reihenfolgebedingungen getestet werden können.
So diese drei Arten von Operationen, die unterscheiden wir einfach.
Die sind in der Regel, ist so eine Kombination dieser Arten von Operationen notwendig,
um eine runde Schnittstelle für eine Klasse, für eine Komponente zu entwickeln.
So, den Überweiser wollen wir jetzt interaktiv benutzen.
Also da soll so eine grafische Oberfläche drauf. Und das,
was man sich so bildlich vorstellen kann oder das,
warum ich sie bitte, sich das so bildlich vorzustellen.
Da kommen also so Ereignisse, kommen von außen,
also sowas wie Maus die sich bewegt und dann wird also
ein Knopf gedrückt oder es wird also, ein Betrag wird eingegeben.
Das heißt also von der Art der Benutzung her gibt es also so eine Komponente,
eine Klasse, die ist für die Interaktion zuständig und die muss das,
was da so dieser Strom von Ereignissen,
der hier entgegengenommen wird von dieser, von einem Objekt dieser Klasse,
der muss also an die Klasse überweisen,
an ein Objekt der Klasse überweisen zur Laufzeit müssen diese Ereignisse übertragen werden,
übergeben werden als Parameter.
So technisch gesprochen heißt es also, die Interaktion muss den Überweiser benutzen Und dann,
wenn der seinen Zustand ändert, muss der aber auch sagen,
hey, das hat sich jetzt, also irgendwelche Daten haben sich geändert,
dann muss der Überweiser die Interaktion benutzen.
Das soll ja auch wieder an der Oberfläche etwas dargestellt werden,
wenn sich, also aufgrund einer Überweisung, meinetwegen die Kontostände geändert haben,
dann muss das ja auch an der Oberfläche wieder dargestellt werden.
So, das ist also,
was wir uns jetzt gerade hier modelliert haben,
ist eine zyklische Benutztbeziehung und wenn Sie mal So sich dieses etwas chaotische Bild vom Anfang nochmal vergegenwärtigen.
Zyklische Benutztbeziehung ist etwas, das wollen wir vermeiden.
Das ist in der Softwareentwicklung ist das so ein großes Problem.
Das können wir technisch, können wir das leicht realisieren.
Das ist aber, führt regelmäßig zu schlecht wartbarer Software.
So ein Grund, sie werden noch verschiedene andere Gründe kennenlernen.
Ein Grund dafür, dass man da so zyklische Benutzbeziehungen vermeiden möchte,
ist, man kann diese Klassen nicht mehr getrennt voneinander testen
Die benutzen sich halt wechselseitig und ich kann nicht,
also jetzt die unabhängig voneinander testen und das ist schon mal etwas,
was ich überhaupt gar nicht schätze,
was ist die langfristige Wartbarkeit eines Systems, also ziemlich zerstört.
Das Problem haben wir aber trotzdem,
also wir haben nicht dieses zyklische Problem,
also wir haben das Problem, es kommt hier ein Strom von Ereignissen,
das impliziert, dass diese Art von,
dass diese Richtung hier vorgegeben ist und wir haben aber,
und gleichzeitig das Problem.
Wir müssen etwas an der Oberfläche darstellen. Das Rückkopplungsproblem ist
also mit dem Instrumentarium, das wir im Moment haben,
nicht anders lösbar als durch eine zyklische Benutztbeziehung.
Jetzt sage ich Ihnen, das wollen wir nicht.
Jetzt muss uns also noch was einfallen. Gott sei Dank ist
den Leuten noch mal was eingefallen und ich komme jetzt mal,
wie geht es dahin ein? Also wie kann ich dieses
grundsätzliche Rückkopplungsproblem, wie kann ich das lösen? So,
jetzt sehen Sie einen den ersten Vorschlag wieder zu bewerten ist,
sehen Sie ja an diesem Zeichen. Die Interaktion ruft,
also jedes Mal, wenn sie ein Ereignis ange,
wenn so ein Ereignis an den Über-Ur-Überweiser An den Überweiser weitergeleitet worden ist,
ruft sie den Überweiser auf und fragt, also soll ich was anderes darstellen?
Das kann man machen. Ist aber nicht so softwaretechnisch ist das,
ist das nicht so sauber,
weil die Interaktion soll eigentlich keine Kenntnis darüber haben,
ob so irgendwas, was da jetzt eingegeben worden ist,
ob das einen Effekt hat.
Die Interaktion ist für die Interaktion zuständig. Eine Klasse,
eine Zuständigkeit und sie soll nicht,
also sich darum kümmern, was das fachlich eigentlich bedeutet.
Also die Lösung ist nicht so toll. Die andere Lösung
Hatten wir bereits gesagt, also in dem Moment,
wo also hier was angekommen ist und der Überweiser merkt,
also er hat einen anderen Zustand, soll er doch die Interaktion aufrufen.
Das ist dann genau diese zyklische Benutzbeziehung, die wir eigentlich vermeiden wollten.
Die dritte Lösung, die geht jetzt in die richtige Richtung. Das ist das sogenannte,
also als nicht, also als muttersprachlich Deutscher,
tendiere ich jetzt dazu, dass hier als Polling auszusprechen,
wie mir eine muttersprachliche Engländerin mal gesagt hat,
Guido,
das sprechen
wir Powling
Okay, gut. Also bitte, jetzt,
wenn Sie das jetzt, Polling in Zukunft nennen,
ist das Ihr Problem, ich habe es Ihnen gesagt,
das spricht man Powling.
Das Powling besteht darin, dieses Prinzip, ganz unabhängig davon,
also was hier jetzt in der Interaktion an Ereignissen an den Überweiser übergeben worden ist.
Ich frage einfach immer nach, gibt es
was Neues darzustellen
Also das ist ständige Sondieren. Also gibt es was anderes
darzustellen? Und wenn ja, dann tue ich das.
Also dafür habe ich ja die Sondierenden Operationen an dem Überweiser.
So sind also auch viele technische Systeme, also genau so implementiert.
Das ist bloß ein bisschen, also ineffizient. Also wenn man,
also ständig nachfragt, also es vermeidet,
also die Probleme der beiden anderen Lösungen,
aber das ist so die Richtung, in die wir wollen.
Das müssen wir uns nur noch mit dieser Effizienzfrage auseinandersetzen.
Also wie kriege ich das hin,
dass nicht ständig gefragt werden muss?
Und die Grundidee ist dabei,
der sogenannte Benachrichtigte Beobachter
Die Interaktion beobachtet den Überweiser, in dem Sinne,
dass der Überweiser so eine kleine, so eine,
so eine kleine Glocke, also metaphorisch gesprochen,
so eine kleine Glocke läutet, wenn er weiß,
also wenn der Überweiser sagt, ich habe meinen Zustand geändert,
dann gibt er so ein einzelnes Glockenzeichen und dann wird die Interaktion sondieren.
So diese, das heißt jetzt erstmal nichts anderes als Ich reduziere
die Interaktion zwischen dem, das sollte ich jetzt nicht sagen,
ich reduziere die Rückkopplung zwischen dem Überweiser und der Interaktion auf diesen einzelnen Glockenschlag.
Das ist etwas, was ich, dazu möchte ich eigentlich
ein sprachliches Mittel in der, ein Mittel in der Programmiersprache haben.
Und es gibt auch so Tendenzen in die Richtung,
Also die Folie ist schon, also zu dem Zeitpunkt,
als sie gemacht wurde, gab es tatsächlich keine einzige gängige,
objektorientierte Programmiersprache, in der man so einen Signalmechanismus derartig in der Sprache hatte, dass man so einen anonymes Ping geben konnte.
Es gibt aber Tendenzen, so, ich glaube, C-Sharp-Fred. Ist das so in C-Sharp,
also gibt es so einen Mechanismus in Java,
gibt es das, also mindestens noch nicht, also das,
ich weiß nicht, ob das in Java 11 oder 12,
oder weiß man halt nicht, so,
aber so die Grundidee ist, also das wird langsam,
aber sicher kommt das so in die Programmiersprache hinein,
dass man von einem Objekt ein Signal Ein Signal an ein anderes Objekt senden kann,
ohne dass man weiß, dass da jemand ist,
der dieses Signal beachtet.
Es geht einfach nur darum, mitzuteilen,
es hat sich etwas geändert und wenn das jemand interessiert,
dann kann er mit Sondierenden Operationen darauf reagieren.
Wie wird das jetzt in einer Sprache, in der es
diesen Mechanismus nicht gibt, wie wird das in so einer Sprache implementiert?
Und dafür gibt es dieses Entwurfsmuster des Beobachters. So,
jetzt kommen wir zu dieser Mikroarchitektur. Wenn Sie also dieses Problem haben,
ist jemand, der hat seinen Zustand geändert und denkt,
möglicherweise interessiert das jemanden, dann soll dazu das Entwurfsmuster Beobachter verwendet werden.
Und die prinzipielle Lösung dieses, oder die prinzipielle Herangehensweise, sehen Sie hier.
Es gibt dieses Entwurfsmusterbeobachter, besteht aus zwei Komponenten.
Es gibt einmal so eine abstrakte Klasse, die heißt beobachtbar.
Von der soll man erben, wenn man beobachtet werden möchte.
Also möglicherweise jemanden mitteilen möchte, dass man sich geändert hat
Diese abstrakte Klasse beobachtbar. Der kann man also,
wenn man von der geerbt hat, dann wird man einen Beobachter setzen können.
Also das ist ein Beobachter setzen können. Und worauf man
sich dann verlassen kann, ist in dem Moment,
wo man an sich selbst die Operation melde, Änderung aufruft,
dass an allen gesetzten Beobachtern die Operation beachte Änderung aufgerufen wird.
Die Operation beachte Änderung, die ist ein,
also es ist der einzige,
so wie das hier jetzt so vorgeschlagen wird,
ist,
dass die einzige Operation des Interfaces beobachte
Das heißt, wenn ich jemanden beobachten möchte,
dann implementiere ich dieses Interface und ich kann davon ausgehen,
wenn der von mir beobachtete, also sich geändert hat,
dann wird er bei mir die Operation,
beachte Änderung aufrufen.
Und da ist hier ein Interface ist, kann ich entscheiden,
also wie ich diese Operation implementieren möchte.
Und jetzt, so hoffe ich,
dass bei Ihnen so ein Gedanke auftaucht wie toll
Da wäre ich nie selbst drauf gekommen. Also jedenfalls nicht
unmittelbar. Diejenigen von innen, die sagen, ja,
klar, wie soll man denn das Problem sonst anders lösen?
Herzlichen Glückwunsch, aus Ihnen wird noch was. Aus den anderen auch
, aber so aus der zweiten Gruppe wird garantiert was.
So, jetzt gucken wir uns das nochmal im Kontext unseres Überweisers an.
Der Überweiser ist also die Komponente, die wir beobachtbar machen wollen.
Also erbt die von der abstrakten Klasse beobachtbar so was die halt hier tut,
ist in dem Moment, wo meinetwegen der Auftraggebersaldo sich verändert hat,
ruft die die Operation Melde Änderung auf.
Melde Änderung bedeutet, alle Beobachter, alle registrierten Beobachtern bei
allen registrierten Beobachtern wird die Operation beachte Änderung aufgerufen.
Die Interaktion, dass wir die Komponente, wo bei der,
die der Strom von Ereignissen ankommt Die benutzt also die Klasse Überweiser und sagt halt so,
hier ist ein Saldo eingegeben worden und so weiter.
Und in dem Moment, wo jetzt eine veränderte Oberfläche dargestellt werden soll,
kann sie sich jetzt als Beobachter beim Überweiser darauf verlassen,
dass bei ihr die Operation beachte Änderung aufgerufen wird.
So, und die Implementation von Beacht Änderungen besteht dann darin,
na, ich lasse mir mal von dem Überweiser geben,
den Zustand geben und den aktualisierten Zustand, den zeige ich dann an.
Vola. Ja, so haben wir jetzt das grundsätzliche Problem
Eine Klasse möchte, eine Zustandsänderung einer Umgebung mitteilen,
ohne diese Umgebung zu kennen. Dieses Problem haben wir jetzt
gerade unter Verwendung des Entwurfsmusters, Beobachter gelöst. So,
und das hat jetzt, also ich will nicht,
das ist jetzt weder über noch untertreiben, aber das hat ziemlich große Konsequenzen.
Dramatische Konsequenzen, ein kleiner Schritt für die Menschheit, ein großer Schritt für sie.
Jetzt können Sie nämlich sagen, zu Ihrem Nachbarn, Programmierteam.
Ich habe um dieses Problem da vorne zu lösen,
habe ich das Beobachtermuster angewendet. Und dann sagt er,
alles klar, dann haben sie eine Sprachebene jetzt entwickelt,
mit der sie ja so, ich will nicht sagen mit einem Wimpernschlag,
aber doch mit zwei Zungenschlägen,
können sie also so einen Haufen Informationen übertragen.
Einfach in Kenntnis dieser Menge von Entwurfsmustern,
die wir ihnen hier im Laufe dieser Veranstaltung und im Verlaufe
von weiteren Veranstaltungen
beibringen werden
Auch noch nachlesen. Ich habe gleich noch Literaturhinweis für sie. Und das ist,
das macht Softwareentwicklung dann so auf einer anderen Ebene für sie möglich.
Sie können nämlich jetzt darüber sprechen, was sie tun.
Und wenn sie so viele Worte brauchen, könnte es sein,
dass ein erfahrenerer Entwickler, als sie sie dann mal fragt,
warum machst du das nicht mit dem Entwurfsmuster Fabrik?
Okay, womit lest es mal nach? Wenn er arrogant ist,
wenn er nett ist, sagt er ihnen, also Fabrik geht so.
Und jetzt hoffe ich, habe ich eh so ein klein
wenig motiviert, sich mit Entwurfsmustern im Weiteren zu beschäftigen.
So diese Beschreibung von Entwurfsmustern ist dann, ist selber auch wieder Musterartig.
Also es ist ja eigentlich immer dasselbe. Die Dinger haben
einen Namen und die haben einen Zweck. Das ist der Kontext,
also das Problem, für das sie geschaffen worden sind.
Und dann wird noch gesagt, also wann man sie,
mit welchem Motiv anwenden kann. Und es gibt da jetzt
eine ganze Reihe von so verschiedenen Kochbüchern, in Anführungsstrichen,
Also die Ihnen sagen, wie so ein Muster dann beschrieben werden. Das ist so,
ob man da jetzt so die von Gamma at All verwendete Notation verwendet,
so diese besteht, glaube ich, so aus acht verschiedenen,
aus acht verschiedenen Teilkomponenten oder Bausteinen oder ob man das hier mit 1 zu 3,
4, 5 fünf Elementen macht, ist eigentlich Pott,
es hört sich jetzt,
das ist nachrangig,
ist nicht allzu unwissenschaftlich auszudrücken
Entscheidende ist, so ist es eigentlich hier so auf der Seite dargestellt.
Das Dinger, die Dinger haben immer einen Namen,
sie sind für ein bestimmtes Problem gut. Es gibt einen Kontext,
in dem dieses Problem existiert und es sagt so,
so wie sieht denn die prinzipielle Lösung aus? Also das,
was ich ihnen ja jetzt nahegelegt habe, das mit Beobachtermuster,
so besteht aus einer abstrakten Klasse beobachtbar und einem Interface-Beobachter,
das kann man so machen.
Das hat dann aber auch bestimmte Konsequenzen. Die positive Konsequenz ist,
wir haben jetzt also dieses Rückkopplungsproblem, haben wir gelöst,
das Negative an dieser Implementationsidee, Skizze, die ich jetzt gerade gezeigt habe,
ist, Also ich bin nicht allzu ausdrucksstark, oder?
Ich kann halt sagen, ping, es hat sich was geändert,
aber was sich jetzt geändert hat, kann ich nicht ausdrücken.
Ich habe ja nur ein einzelnes Ping. Im Übrigen,
ach, das frage ich eigentlich jedes Jahr. Wer sagt,
zu wem, in welchem Film geben sie ihm ein einzelnes Ping?
Mal handhoch, wer den Film gesehen hat.
Es werden jedes Jahr weniger. Es muss mit ihnen zusammenhängen
. Also die Jagd auf rote Oktober,
es ist so ein etwas schräger,
so ein U-Boot-Film,
lassen wir das
So, ich habe ja nur so ein einzelnes Ping,
jetzt könnte ich mir ja vorstellen, ich bin auch etwas ausdrucksstärker.
Ich sage dann an meiner Schnittstelle, ich habe diese Zustandsänderung,
kann ich mitteilen und jene und jene.
Man kann sich also für eine bestimmte Zustandsänderung bei mir registrieren,
sodass nicht jeder Zuhörer sämtliche Änderungsmitteilungen bekommt,
sondern nur die, für die er sich registriert hat.
Das ist konstruktiv
ein bisschen aufwendiger
Bei der Implementation, ist dann aber im Ablauf etwas effizienter.
Stellt man sich mal vor, so eine Klasse wie der Überweiser,
der hat so, sagen wir mal, 10,
20 verschiedene Änderungen, kann der mitteilen.
Wenn mich aber bloß eine davon interessiert und ich muss
immer hingucken, also ist das jetzt relevant für mich?
Das ist vielleicht auch lästig, weil ich jetzt gerade,
wenn ich mich so reden höre, also ich glaube nicht,
dass Objekte Gefühle haben, aber es ist ineffizient.
So, Entwurfsmuster sind also solche Mikroarchitekturen, Und diese Mikroarchitekturen,
ich habe das schon gesagt, sind so Elemente einer Sprache,
die sie jetzt so langsam aber sicher lernen werden.
Und das, was wir ihnen so, so das erste Buch,
das zu dem Thema, oder das berühmteste Buch,
das zu diesem Thema geschrieben worden ist,
ist also von der sogenannten Gang of 4,
das sind also vier Herren in diesem Fall gewesen,
die also 23 Entwurfsmuster klassifiziert haben
Also sie sehen die hier, die haben so unterschiedliche Aufgaben,
sind die entwickelt worden und die haben im Großen und Ganzen,
was die getan haben, ist halt diese Meisterleistung ist,
die Probleme, die sie über die Jahre, wenn nicht sogar Jahrzehnte,
mit objektorientierten Entwürfen, also gehabt und gelöst haben,
sie haben sie benannt und haben gesagt, so macht man das,
wenn man dieses Problem hat, Und dieses Problem hat,
dieses Rückkopplungsproblem hat, dann benutzt man doch,
dann schlagen wir hier mit vor, versucht es,
das Problem doch mal mit dem Beobachtermuster zu lösen.
Oder wenn man das Problem hat, ich möchte nicht nur mitteilen,
dass ich, also dass ich meinen Zustand geändert hat,
sondern ich möchte einem möglicherweise mir im Moment noch nicht bekannten Vermittler,
den möchte ich darum bitten, ein Problem zu lösen,
von dem ich weiß, dass ich es nicht lösen kann,
aber von dem ich erwarte, dass er es für mich lösen kann,
dann möchte ich jetzt die zuständig schlagen, vor,
man möge doch die zuständig,
die sogenannte Zuständigkeitskette verwenden.
Das ist dann nämlich so ein anderes, also Problem,
also beim Beobachter sagt man ja,
ich habe mich geändert, ich sage das jetzt mal,
ob es jemanden interessiert, das ist mir eigentlich egal.
Ich erwarte auch keine Reaktionen darauf. Aber wenn ich ein
Problem habe, dass ich von jemandem gelöst haben möchte,
dann erwarte ich, dass ich eine Antwort bekomme.
Und wenn die Antwort nur ist, hilft dir selbst.
Aber dann weiß ich wenigstens Bescheid, dann erwarte ich eine Antwort und dann kriege ich auch eine Antwort. Wenn das mein Problem ist, dann verwende ich die Zuständigkeitskette. So,
und jetzt gibt es Also diese 23 Entwurfsmuster,
das hier, das ist mittlerweile gibt es,
also hunderte von Entwurfsmustern, die publiziert worden sind,
aber das ist so die entscheidende Nachricht für sie,
hoffe ich jedenfalls heute ist,
also es gibt diese Sammelwerk und da kann man mal reingucken und das Buch,
der Gang of 4 von den Herren Gamma Helms,
Fliesididis und Johnson, das steht auch in ausreichender Anzahl,
glaube ich, in der Bibliothek zur Verfügung,
das ist halt der Klassiker der Softwaretechnik mittlerweile,
Elements of Reusable Object Oriented Software,
da werden diese Entwurfsmuster so beschrieben,
wie ich das jetzt gerade so für das Beobachtermuster vorgestellt habe
Und das kann Ihnen helfen. Also da kann man einfach mal nachgucken,
welche Arten von Problemen haben die schon mal so für ein prototypisch gelöst.
Und es kann Ihnen dann helfen, diese Art von Lösung
in Ihre Programme zu integrieren und dann mit anderen Entwicklern,
die auch über dieses Sprach, über diese Sprachmittel verfügen,
einfacher zu ihre Entwürfe zu kommunizieren. Und nicht nur das,
sondern man kann ja dann auch, also so über Qualität,
also von Softwareentwürfen, kann man dann auch besser sprechen,
weil wenn diese Art von Entwurfsmustern in das Design so mit reingehen ihrer Software-Systeme,
dann ist das ja auch ein Qualitätsmerkmal,
anstatt also sagen zu müssen, ich habe das so gelöst,
weil mir ist nichts keine andere Lösung eingefallen,
was ja nicht besonders ingenieurwissenschaftlich ist.
Sie kennen also jetzt, mindestens haben Sie schon mal einen Hinweis darauf,
dass es diese Kataloge gibt und den hier kann ich
Ihnen so als Wochenendlektüre nur wärmstens empfehlen.
Apropos Wochenendlektüre, dann wünsche ich Ihnen jetzt ein schönes Wochenende
und übergebe an Fred
Bis demnächst. Untertitel der Amara.org-Community Untertitel der Amara.org-Community Musik So
, ich höre mich selbst. Ich hoffe, ihr hört
mich auch. War so ein bisschen so. Ja,
ich rede einfach mal ein bisschen, damit die Stimme eingepegelt
werden kann und versuche gleichzeitig irgendwas Sinnvolles auf meinem Rechner zu machen.
Ich kann ja einfach mal
Eclipse starten
Nee, Internet wäre schon nicht schlecht, wenn ich es hätte.
Ich stoße hier ständig mit den Lippen gegen das Mikro.
So, muss jetzt wahrscheinlich neu eingepegelt werden,
weil es jetzt nicht mehr so nah dran ist.
Habe ich Eclipse schon gestartet? Ich glaube nicht,
oder? So, das ist der Startbildschirm.
Dann starte ich mal meinen Text-Edge-Talk, der startet deutlich schneller.
Gut, was will ich denn heute alles mit euch machen?
Also ich wollte einmal nochmal den Bug, den wir letzte Woche hatten.
Da ist mir im Nachhinein eingefallen, den hätten wir so einfach finden können.
Und ich wollte es euch einfach nochmal zeigen.
Also wir haben ja letzte Woche irgendwie fünf Minuten nach
einem Bug gesucht
Da hatte ich also diesen Parameter von der Methode Startelement,
den hatte ich blöderweise auch hier unten in der Methode Entelement.
Ja, der klebt dann einfach so hinter, warum?
Weil ich mir natürlich ganz blöd mit Copy und Paste einfach hier
diesen Methodenkopf kopiert hatte, hatte den einfach so hier runtergetan,
so einfach hingepastet und habe dann das Start durch End ersetzt und dachte, super.
Und dann hatten wir ja festgestellt, dass diese Methode gar nicht aufgerufen wird.
Ja, kennt jemand eine Möglichkeit zu sagen, lieber Java-Compiler,
ich möchte hier eine Methode aus einer Oberklasse ersetzen,
bitte prüfe, dass ich das tue.
Ich lasse mal kurz zehn Sekunden die Leute darüber nachdenken,
vielleicht könnte sowas ja eine Klausurfrage sein.
Drei Leute melden sich,
so wenig
Vier? Overright, genau. Und ich kann das zum Beispiel
an dieser Stelle, ne, Entschuldigung, wo ist meine Startmethode?
Hier ist sie, ne? Also hier wird der Kompala mehr sagen,
ah, der Programmierer will, dass ich prüfe,
dass es hier wirklich ein Overright ist.
Was wird er dann machen? Er wird sich ja diese
Signatur angucken. Dann wird er in der Oberklasse gucken,
gibt es da eine Methode mit derselben Signatur und dann funktioniert das alles.
Während wenn ich das hier unten gesagt hätte,
dann hätte der Kompala sich beschwert.
Genau. Mal gucken, was jetzt die Fehlermeldung ist,
ob wir das verstehen
Okay, The Method and Element, bla bla bla,
must overright or implement is Supertype Method. Er sagt also,
es gibt keine solche Methode im Typ über dir.
Wenn du hier wirklich was überschreiben wolltest, dann hast du was falsch gemacht.
Wenn ich das jetzt also hier wieder wegnehme. Zack.
Dann ist der Compiler zufrieden. Also dieses Ed Overred kann
einem wirklich viel Schmerzen ersparen. Ich tendiere manchmal dazu,
die wegzulöschen, weil die einfach Platz auf dem Bildschirm brauchen.
Das ist eigentlich Unsinn heutzutage. Die zehn Bytes,
die man hier zusätzlich braucht, sind eigentlich egal.
Gut, hätten wir uns fünf Minuten sparen können letztes Mal.
Was wollte ich als nächstes mit euch machen
Genau, ich wollte noch mal über die Entwurfsregeln rübergehen.
Was haben die Entwurfsregeln zu tun mit dem Beobachtermuster?
Also gehe ich in die Entwurfsregeln. Hier sind sie.
Und ich wollte zwei Stellen mir angucken mit euch.
Einmal dieses wunderbar tolle Diagramm. Wo taucht jetzt in diesen vier Element-Typen?
Das Beobachtermuster auf. Das taucht an zwei verschiedenen Stellen auf.
Einmal eine Stelle, die in letzter Zeit anderen Orts
kontrovers diskutiert wurde, ob das so sinnvoll ist.
Also in unseren Entwurfsregeln ist es so,
dass Werkzeuge Services beobachten. Es kann also durchaus sein,
dass verschiedene Werkzeuge sagen, ich interessiere mich dafür,
wenn sich in dem Service irgendwas tut.
Ich will benachrichtigt werden,
wenn sich in einem Service was tut,
um darauf entsprechend zu reagieren
Das also das eine, quasi hier in Zwischenwerkzeug und Service
, kann es eine Beobachtungsbeziehung geben.
Und zwischen verschiedenen Services, das sieht man jetzt hier nicht,
weil hier nur einmal der Typ Service steht.
Also verschiedene... Stimmt, das kann passieren,
das ist für uns aber gar nicht interessant.
Tatsächlich gibt es in dem System das auch. Und eine dritte Variante,
auf die ich eigentlich zu sprechen kommen wollte, ist die hier.
Werkzeuge können sich auch beobachten. Und warum das sinnvoll ist,
das wollte ich mir einmal mit euch angucken.
Warum ist es sinnvoll, dass bei Werkzeugen beobachtet wird?
Also wir kriegen diese Woche ein neues System
Ihr könnt also die Mediathek jetzt quasi vergessen.
Jetzt kümmern wir uns um eine andere Anwendungsnomie. Ich starte
das System einfach mal. Kinos. Wir wollen also Leute,
die an der Kinokasse sitzen, dabei unterstützen, Kinokarten zu verkaufen.
Das ist vielleicht nicht so überraschend. Auch schon ein System,
was über viele Jahre gewachsen ist. Und ihr seht,
ach, das sieht ja irgendwie ganz interessant aus.
Hier kann man das irgendwie ein Datum auswählen. Ich kann da irgendwie sagen,
ich will den Tag davor oder den Tag danach haben.
Dann seht ihr zu dem entsprechenden Datum,
also 1.6.2016, das ist zufällig heute,
folgende Filme laufen
Und wenn ich jetzt hier irgendwas anklicke, dann wird man den entsprechenden Kino,
sage ich jetzt sehen, oder sollte zumindest so sein.
Tatsächlich ist es so, wenn ich hier ein Datum auswähle,
ist jetzt zweiter, dritter, vierter, fünfter,
sechster, dann tut sich irgendwie so gar nichts.
Eigentlich würde man ja erwarten, dass ich jetzt hier diese Vorstellungsliste anpasse.
Und wenn ich jetzt hier klicke, dann würde ich erwarten,
die laufen in verschiedenen Seelen und so,
dass sich dann hier irgendwas ändert.
Tut sich aber nichts. Woran liegt das? Wir haben also
hier ein völlig isoliertes Werkzeug, das Datum Auswählwerkzeug heißt es,
glaube ich. Hier ein isoliertes Werkzeug, Vorstellung auswählt Werkzeug.
Und hier ein isoliertes Werkzeug, Platzverkaufswerkzeug,
die noch irgendwie gar nicht so richtig miteinander kommunizieren.
Und die Frage ist, wie sollten Sie es sinnvoll kommunizieren
Und das schauen wir uns mal ganz kurz an.
Der Vorteil ist ja, wir sollen das eigentlich
relativ schnell finden können. Es geht ja um Werkzeuge,
also gehen wir doch mal in das Werkzeugpaket.
Und schaut mal, man hat jetzt hier vier Subpakete.
Warum denn vier und nicht nur drei? Also Datum Auswähler,
das war das mit den beiden Buttons, Tagvortag zurück.
Vorstellungsauswähler, das war das da drunter, wo man sagen konnte,
welche Vorstellung will ich denn gerade haben.
Und Platzverkauf. Warum ist denn da jetzt noch ein viertes Werkzeug?
Ja, das liegt einfach daran, dass wir Werkzeuge gruppieren können.
Wir können sagen, ich habe diese drei Werkzeuge und
ich will sie zusammenfassen in ein sogenanntes Kontextwerkzeug,
nennt man das
ganz gerne
Ja, also dieses Kassenwerkzeug, ich habe das Thema
noch am Starten, ist quasi das ganze Fenster,
wenn ihr so wollt, ja, so ganz grob.
Also das Kassenwerkzeug fasst einfach nur diese drei anderen Werkzeuge zusammen.
Das heißt, wir würden erwarten, dass in diesem Kassenwerkzeug
Quelltext irgendwie ein Bezug zu den anderen Werkzeugen ist.
Das schauen wir uns einmal ganz kurz an. Gibt es
hier irgendwo Abhängigkeiten? Guck mal, hier sind sie schon.
Das ist auch sogar schön, dokumentiert, dass es sich um Subwerkzeuge handelt.
Sehr schön. Also das Kassenwerkzeug besteht aus drei Subwerkzeugen,
nämlich den drei, die ich gerade eben genannt habe.
Okay. Jetzt ist aber das, ja,
das Blöde eben, wenn wir uns zum Beispiel,
wenn man das Datum ausführt,
Werkzeug angucken,
ich kann da ja mal reingehen
Ja, das ist jetzt alles Kram, den versteht ihr noch nicht,
das ist nicht schlimm. Aber es gibt hier irgendwo,
hier zum Beispiel, ja, diese Methode wird immer aufgerufen,
wenn ich auf den Zurückbanden drücke, das steht ja auch darüber.
Und diese Methode wird immer aufgerufen, wenn ich den anderen Button drücke.
Und hier ist noch überhaupt keine Kommunikation mit anderen Werkzeugen.
Ja, und jetzt könnte man vielleicht naiv denken, naja,
ich kann doch jetzt hier einfach eine weitere Zeile Code reinschreiben. Ja,
wenn also der Zurückbutton gedrückt wurde,
ich kann doch einfach eine weitere Zeile Code schreiben,
die an dem Vorstellungs, wie heißt das Ding,
Vorstellungsauflistungswerkzeug oder so, die hier einfach eine entsprechende Methode aufruft,
die sagt, hey, jetzt ist der zweite,
sechste oder jetzt ist der dritte,
sechste oder jetzt ist der vierte, sechste,
aktualisier dich mal.
Ja, das würde aber bedeuten,
dass die Subwerkzeuge untereinander kommunizieren und das wollen wir nicht
so gerne
Wir können ja vielleicht mal, dass ich hier nicht so viel
mit den Händen wedeln muss, weil meine Lieblingsentwicklungsumgebung geht.
Da muss man immer nicht so viel programmieren, sondern nur zeichnen.
Und ich will diesen Zusammenhang euch einmal ganz kurz klar machen,
wovon ich hier die ganze Zeit rede.
Also, wir haben hier dieses Kassenwerkzeug, Carsten, Werkzeug.
So. Dann hatten wir das Datum, Datum aus,
auswählen, Werkzeug oder so ähnlich.
Also wenn ich mich jetzt hier leicht im Namen vertippe,
bitte nehmt es mir nicht übel,
dann irgendwie Vorstellungsauflister,
Werkzeug oder so ähnlich
Und wie hieß das dritte? Platzverkaufswerkzeug oder so. Platzverkaufswerkzeug. Irgendwie
so ähnlich. Und wir hatten ja eben schon gesehen,
in dieser Klasse hatten wir ja diese drei Abhängigkeiten gesehen.
Kassenwerkzeug hier, diese drei Abhängigkeiten. Die kann ich aber
einzeichnen in das Diagramm, dass wir das einfach mal gesehen haben,
zack, zack, zack, zack.
Ja, das ist bis jetzt die Struktur.
Das versteht man doch eigentlich ganz gut, oder?
Das ist so das übergeordnete Kassenwerkzeug, das fasst irgendwie diese
drei Werkzeuge zusammen. Und um die sinnvoll zusammenfassen zu können,
muss es die natürlich kennen
Ja, weil die werden ja erzeugt von dem Kassenwerkzeug und so weiter.
Und was mein Vorschlag gerade war, war zu sagen, hey,
das Datum aus wie Werkzeug könnte doch einfach den Vorstellungsauflüster sagen,
das ist jetzt ein anderes Datum ist,
das würde ja dann irgendwie so aussehen müssen.
Ich hätte dann eine weitere Abhängigkeit. Das heißt,
auf Code-Ebene müsste ich dann hier eine Referenz auf dieses Werkzeug haben. Ja,
und wahrscheinlich müsste ich dann auch von hier eine Referenz noch da haben,
denn jedes Mal, wenn eine andere Vorstellung ausgewählt wird,
muss ja dann entsprechend der Kinosaal richtig angezeigt werden.
Das sieht irgendwie nicht so schön strukturiert aus,
obwohl das jetzt hier so schön nur horizontal in die Richtung geht und vertikal in die.
Aber wir wollen das eigentlich nicht. Wir wollen eigentlich nicht
, dass Subwerkzeuge miteinander kommunizieren
Warum? Ja, also in diesen kleinen Lollipop-Systemen ist das vielleicht
immer nicht so offensichtlich. Ich habe mal einen Herren befragt,
der sich ganz gut mit solchen Fragen auskennt,
beziehungsweise ich habe mich natürlich nicht selber gefragt, sondern jemand anders.
Es gibt also wunderbar interessante Bücher, wo Programmierheroes interviewt werden.
Und wo sie zum Beispiel auch so gefragt werden,
wie liest du eigentlich ein Programm, was du selber gar nicht geschrieben hast?
Wie gehst du da ran oder wo sind da die Probleme,
welche Herausforderungen sind und so? Und ich habe mir das
rausgesucht, was ich hier am interessantesten fand. Genau,
also eigentlich ist es dieser erste Satz, der reicht eigentlich schon.
Also ich möchte kleine Teile dieses Systems für sich verstehen können. Das heißt also,
auf unser Diagramm übertragen, Wenn ich das Datum auswähle,
Werkzeug verstehen will und ich habe diese Abhängigkeit,
die ich jetzt gerade wieder rausgelöscht habe, und ich habe diese Abhängigkeit,
dann kann ich das Datum auswählwerkzeug nicht verstehen,
ohne das Vorstellungsauflüsterwerkzeug zu verstehen und dann auch,
wie es dem mathematisch ausdrückt dafür,
wenn es dann auch so weitergeht, transitiv.
Transitiv muss ich dann auch noch das Platzwerkzeug verstehen, ja.
Und ihr könnt euch vorstellen, eigentlich ist das Datum auswählwerkzeug
total billig, diese beiden Knöpfe und so ein Datum.
Ich will eigentlich gar nicht wissen, dass es
diese Abhängigkeiten irgendwie gibt. Ich will die nicht haben.
Ich will das für sich verstehen können,
das für sich verstehen können und
das für sich verstehen können
Und deswegen bauen wir uns jetzt so ein bisschen zusätzliche Komplexität durch
dieses Beobachtermuster an das System. Was aber den Vorteil hat,
dass wir eben einfacher die Komponenten verstehen können, unabhängig voneinander.
Und ganz generell gilt es natürlich, je weniger Abhängigkeit man
hat, desto einfacher sind die Komponenten testbar.
Das ist jetzt hier nicht so spannend, weil wir grüßen eigentlich selten testen.
Aber für das Verständnis finde ich das eigentlich ganz nett.
Und natürlich auch, ihr könnt euch vorstellen,
Stellt euch doch mal vor, ihr habt diese harte Abhängigkeit.
Jedes Mal, wenn ich den Pfeil drücke, wird auf
diesem Werkzeug eine Methode aufgerufen. Und jetzt merkt ihr irgendwie nächste Woche,
oh, an einer anderen Stelle im System hätte ich auch gerne so ein Datum auswählen,
Werkzeug, weil ich da vielleicht Mails anzeigen will,
die zu einem bestimmten Datum eingegangen sind oder irgendwelche Rechnungen zu bestimmten Daten.
Und dann ist es irgendwie blöd,
dann könnt ihr dieses Datum aus für Werkzeug nicht woanders verwenden,
ohne dieses Werkzeug, was dann mit Mails oder Rechnungen ja gar nichts zu tun hat.
Also entkoppeln, wir wollen die Komponenten immer möglichst gut voneinander entkoppeln,
um sie in anderen Kontexten einsetzen zu können.
Und wenn ihr dieses Buch lest über Entwurfsmuster,
auf jeder Seite steht das Wort Reuse, also Wiederverwendung,
das wird also ganz groß hervorgehoben.
Okay, habe ich damit gesagt, was ich sagen wollte?
Ich glaube ja. Genau. Und ja,
also möglicherweise könnt ihr das jetzt noch nicht so richtig nachvollziehen,
wenn ihr dann in der Berufspraxis mal mit richtig großen Systemen zu tun habt.
Erinnert euch vielleicht an diese Vorlesung und denkt so,
hach, vielleicht kann ich das System so ein bisschen entkoppeln,
so ein bisschen entzerren,
dass ich diese Komponente jetzt auch mal hier einsetzen kann und dass sie nicht so fest nur in diesem Kontext funktioniert.
Also ihr müsst jetzt nicht in jedem System zehn Beobachter einbauen,
nur weil ich euch das heute zeige. Ich hoffe,
ihr erinnert euch dann einfach in zwei, drei Jahren daran,
ach, da gibt es doch eine sinnvolle Lösung.
Gut. Okay
Habe ich das jetzt alles gemacht? Übungsaufgabe motivieren da,
da, genau. Okay, und das ist gerade mal fünf Minuten.
Ich bin ja unglaublich schnell heute. Dann kann ich das
ja hier wieder zumachen. Das sollt ihr ja selber tun.
Soll ich das speichern? Ich mache es einfach mal.
Ich glaube zwar nicht, dass ich es nochmal brauche.
Okay, dann schließe ich das. Und was ich ja immer gerne mache,
ist, ja, ein eigenes System vorzustellen,
was ich mit euch zusammen weiterentwickeln will.
Das System heißt Excel. Das will ich euch mal zeigen.
Ich schließe jetzt erstmal hier wieder alles, dass mich das
nicht verwirrt. Wo ist es denn, mein Excel da
ist es
So, es ist ein sehr einfaches System.
Alles in einem Paket, vielleicht gar nicht so hübsch,
aber das ist für so ein kleines System nicht so schlimm.
Und wir starten es einfach mal. Jetzt muss ich
wieder gucken, dass das überhaupt was seht.
So, erzählt ihr was, oder? Okay. Also
nehmt den Namen nicht zu wörtlich. Man kann doch nicht
wahnsinnig viel tun, aber ich kann nicht über irgendwas eingeben.
Vielleicht für irgendeine, ich muss noch Salat kaufen und Olivenöl oder so.
Und jetzt sagt ihr vielleicht, ach Mensch, Fritt,
die Schrift ist so klein, die kann ich ja gar nicht lesen.
Aber ich habe ein ganz tolles Feature eingebaut.
Wenn ich mit dem Causa irgendwo hingehe,
zum Beispiel hier, dann seht ihr oben in Großschrift,
was da steht
Und auch zum Beispiel hier oder hier oder hier.
Und was ihr jetzt auch sehen könnt, ist hier unten,
sollte eigentlich stehen, in welcher Zelle ich gerade bin.
Also irgendwie A-1, B-1, C-1, C-2, C-3, C-4.
Da passiert aber noch nichts. Das ist offenbar noch nicht
verdrahtet miteinander. Ja, und das ist alles, was
man machen kann. Also man kann leider nicht eingeben,
gleich A-2 plus D-2 oder so.
Das ist noch nicht eingebaut, ja. Also man kann
tatsächlich nur so ein paar Texte da reintun.
Mehr kann das System
noch nicht
Okay, dann schauen wir uns doch mal an, wie das System gebaut ist.
Und ich habe es jetzt auch tatsächlich in drei Subwerkzeuge eingeteilt.
Das ist so ein bisschen sehr künstlich. Normalerweise würde man sagen,
das sieht für mich aus wie ein Werkzeug,
aber ich habe tatsächlich gesagt,
dass diese Tabelle ein Subwerkzeug ist, dass diese Start,
diese, wie habe ich es denn hier oben genannt?
Werden wir gleich sehen, dass dieses Ding hier oben auch ein Subwerkzeug ist.
Und diese Statuszeile hier unten, dass die auch ein Subwerkzeug ist.
Und wir gucken mal, wie da die Kommunikation ist.
Warum brauchen die überhaupt Kommunikation? Naja, jedes Mal,
wenn ich hier in eine andere Zelle reingehe,
sei das jetzt per Maus, geht das auch mit Maus?
Tatsache, sei das jetzt per Mausklick oder mit der Tastatur?
Also jedes Mal, wenn sich die aktive Zelle sozusagen ändert,
oder wo sie halt gerade ist, die aktive Zelle,
dann muss das ja dieses Werkzeug irgendwie mitkriegen.
Ja, das soll sich aber jetzt was tun da oben.
Klassisches Problem. Wie kriegen diese Werkzeuge voneinander mit? Und
ich habe es jetzt erst mal nicht so schön gelöst.
Also, wir gucken, wie ist das System gebaut?
Ja, wir gucken jetzt wohl einfach die Start-up-Klasse an.
So, das ist jetzt hier wieder alles blöde Gummi-Magie.
J-Frame, Excel, Excel. Okay,
also Excel ist quasi die eigentliche Hauptklasse aus der Gummi-Perspektive,
sage ich jetzt einfach mal. Und ihr seht jetzt hier
sowas ähnliches, was wir eben auch gesehen haben.
Also, in dieser Klasse Excel Finden wir drei Zustandsfelder zu den Zugwerkzeugen.
Das können wir eigentlich direkt mal darüber schreiben.
Subwerkzeuge. So, Werkzeuge oder vielleicht einen schönen Satz.
Das Contextwerkzeug, Eck. Excel besteht aus drei Subwerkzeugen.
So, ja, aus den folgenden drei Subwerkzeugen.
So, kleiner Kommentar. Okay, also das ist der
sogenannte Magnefire, den ich da oben gezeigt hatte.
Ich starte das sicher noch mal ganz kurz, dass ihr es seht.
Also, dass hier oben ist der Magnefire,
wo man dann irgendwie irgendwas großgeschrieben sieht.
Magnefire, dann haben wir da drunter das Sheet,
das ist diese eigentliche Tabelle. Und dass hier unten,
das ist die Statusleien.
Ja, ich kann das einfach mal da so dalassen.
Okay, jetzt ist ja wieder ganz viel Gui-Kram, das versteht ihr alles noch nicht.
Aber was spannend ist, ist diese Zeile.
Wir hatten ja schon letzte Woche, glaube ich,
hatte ich mal das Wort Dependency Injection in den Mund genommen.
Das klingt immer so hochtrabend. Also was machen wir hier?
Ich erzeuge mir also dieses Sheet, diese Tabelle in der Mitte,
und übergebe diesem Subwerkzeug eine Referenz auf ein anderes Subwerkzeug.
Ich sage also quasi jetzt hier diesem Sheet,
ich gebe dir mal den McNey-Fire,
weil ich gehe in diese Architektur davon aus,
dass das Sheet den Meckenfire kennen muss.
Das ist diese harte Verdrahtung, die wir eigentlich gar nicht haben wollen.
Ich glaube, ich zeichne das einmal direkt,
weil alles, was aus meinem Mund rauskommt,
ist in der fünf Sekunden möglicherweise wieder vergessen,
wenn dann das nächste rauskommt,
also wir zeichnen
Die Excel-Klasse. So, und wie hieß das Ding da oben,
jetzt Magnify? Magnify, wie so eine Lupe quasi.
Das heißt auch Magnify oder tausche ich mich.
Dann haben wir das Sheet. Und dann haben wir
die Statuszeiten des Status leihen. Wir hatten also gesehen,
als ich den Kommentar schrieb, dass es diese drei Subwerkzeuge gibt,
das waren quasi die Abhängigkeiten, die wir vorher auch schon gesehen hatten.
Zack, zack, on zack. Und was ich jetzt
gerade so ein bisschen angemeckert hatte, diese Zeile,
ich stecke den Magnify ja in das Sheet rein,
dann wird er sich das ja sicherlich in ein Exemplarvariabler merken,
schauen wir einmal ganz kurz.
Der Magnefye
Ja. Ach, das ist jetzt Java-Magie, ja.
Also man würde jetzt eigentlich erwarten, dass er sich in
der Exemplar war, ihr habt gemerkt wird.
Das passiert tatsächlich auch im Hintergrund, das sieht man hier aber nicht.
Das ist ein bisschen blöd, technisches Detail, okay.
Aber auf jeden Fall greift das Schied,
seht ihr ja an dieser Stelle auf diesem Magnefire zu.
Also im Quelltext der Klasse Sheet wird mit dem Magnefire was gemacht.
Ich sage an dieser Stelle Magnefire, hey, du musst
deinen Text ändern. Eieiei. Kopplung zwischen diesen beiden Subwerkzeugen,
das wollen wir eigentlich gar nicht haben. Aber gut,
die Kopplung ist jetzt da und dann will ich sie natürlich auch einzeichnen,
also zeichne ich sie ein, dass man es einmal gesehen hat.
Sheet kennt Magnefire, so war das, ne?
Genau. Ja, wollen wir nicht so gerne. Okay,
und wenn ich jetzt will, Dass jedes Mal,
wenn ich jetzt also hier nach rechts gehe, nach unten,
nach links, dass ich hier unten diese Statuszeile ändert,
könnte ich das jetzt natürlich genauso reinhacken in das System,
dann hätte ich eine weitere Abhängigkeit.
Dann müsste ich sagen, gut, dann muss das Sheet eben auch die Statuszeile kennen,
um der zu sagen, hey, ich bin jetzt gerade hier in Cyber sowieso ein Spalte sowieso.
Will ich aber nicht. Was also ein ganz typisches Muster in der Lehre ist,
zu sagen, pass auf, wir haben ja ein System,
das funktioniert zwar, aber es ist nicht so wunderschön gebaut,
wir wollen es jetzt erweitern und wir wollen es jetzt nicht genauso hässlich erweitern,
wie es bis jetzt ist, sondern ich will,
damit du das beobachten musst, er versteht,
erst mal das System so umbauen,
dass es das Beobachten musste einsetzt.
Und wenn wir dann noch Zeit haben,
bauen wir dann dieses zusätzliche Feature ein,
dass die Statuszeile sich immer updatet
Ja, also ich will jetzt diesen Pfeil hier wegkriegen.
Ich hoffe, das kriege ich irgendwie hin. So,
und jetzt habe ich doch auf meinem Plan,
dass wir jetzt das beobachten musste, einzeichnen, oder?
Ausgangssystem verstehen. Ja, genau. Okay, also Ausgangssystem verstehen. Also ist,
auf dieser Ebene noch irgendwie eine Frage zu dem Ausgangssystem.
Da steht jetzt natürlich sehr viel Code drin,
den ihr noch nicht versteht, mit irgendwelchen Actionlisten und so,
das kommt alles noch.
Aber ist diese Struktur erstmal klar, oder gibt es dazu noch Fragen?
Nee, ich habe es extra einfach gemacht.
Gut. Okay, beobachten musste. Woraus bestand denn das
? Also, da muss man immer unheimlich vorsichtig sein.
Also es gab ja einmal den Beobachter und es gab Beobachtbar
Ja schon irgendwie ein Gefühl dafür, welche dieser vier Klassen jeweils Beobachter und welche
beobachtbar sind und welche vielleicht auch gar nichts von allen.
Also vielleicht müssen manche Klassen ja auch weder das eine noch das andere sein.
Der erste hat ein Gefühl, sonst noch jemand,
da hat ein Zwei dann gefühlt, dritter, solange,
ah, du hast heute auch noch nichts gesagt.
Ja, ich dachte die Dame vor dir, oder?
Achso, oder der Herr vor dir ist auch okay.
Ah, du möchtest Sheet beobachtbar machen,
Richtig, weil hier ändern sich ja Dinge und das wollen andere Leute wissen.
Also das muss irgendwie beobachtbar sein, ja.
Und vielleicht jemand anders wäre, wäre jetzt ein Beobachter,
wer soll dieses Sheet beobachten?
Ja. Excel vielleicht, genau. Diese Vermutung können wir
schon mal einzeichnen. Also ich zeichne den Beobachter ein.
Beobachte. Und ich kopiere mir das jetzt hier mal,
den Grund werdet ihr gleich verstehen. Kann ich nicht sagen,
Schiff und dann Ende und dann ist es markiert.
Aber es ist markiert, aber ich kann es nicht sehen.
Alles klar. Also, Excel soll der Beobachter sein,
dann machen wir doch mal, oh Gott,
welchen Fall nehme ich denn jetzt?
Implements Interface
Das sieht auch ganz gut aus, oder? Und dann
haben wir das Sheet, soll beobachtebarer sein, beobachtbar.
Und jetzt mache ich jetzt hier einmal ganz schnell Copy und Pace,
weil ich diese Klammern sonst immer nicht hinbekomme und sage,
hier, Klaas, nee, Abstract.
So, Entschuldigung, Klaas, Klaas ist ja selbstverständlich.
Ja, war das nicht irgendwie so, dass man
diese abstrakte Klasse beobachtbar hatte und dieses Interface-Beobachter, okay.
So, was habe ich denn jetzt hier für einen Pfeil?
In Harrods from, klingt irgendwie gut.
So. Ich hoffe, das ist der richtige Fall.
Okay, was ist mit Magney Fire und Status Line?
Will ich beobachtet werden, nee, Entschuldigung,
soll irgendjemand benachrichtigt werden, wenn sich hier was put,
tut sich da überhaupt irgendwas
Genau. Also momentan Zustand zeigen die nur was an.
Ich kann mit denen eigentlich gar nichts machen. Man kann
sich später vielleicht noch vorstellen, das ist jetzt wieder Zukunftsmusik,
hey, steht das System noch irgendwo hier?
Wäre es nicht auch cool, wenn ich den Text hier oben ändern könnte?
Könnt ihr dann zu Hause als keine Hausaufgabe machen?
Okay. Gut. Das als erste Übersicht, jetzt ist es
aber so, hier fehlen ja noch alle möglichen Dinge.
Fangen wir vielleicht mal beim Beobachtbar an.
Ja, Attribute und Methoden
Hat jemand auch die Folien von Lido im Kopf oder kennt das beobachtet?
Muss doch so gut, dass er jetzt schon sagen kann,
damit etwas beobachtbar sein kann, muss es über irgendwelche Zustandsfelder verfügen.
Ist das noch irgendwie ich? Was natürlich jetzt
gerade heute erst gelernt, jetzt schon rezitieren, ja.
Aha, wir brauchen eine Liste von Beobachtern,
das ist ja interessant, ja.
Ah, wir müssen Beobachter registrieren, das ist auch interessant.
Sagen wir mal, worum wir es registrieren nennen?
Beobachter.
Ah, Überendung von mir. Dann nenne ich das nochmal,
informiere über Änderungen. Cho. Das ist schon gar nicht schlecht.
Sehr schön. Also, warum braucht man so eine Liste? Ja,
also, nehmen wir mal an, ihr würdet mich beobachten,
das ist immer so ein bisschen an den Haaren herbeigezogen.
Wenn ich euch jetzt also irgendwelche Neuigkeiten zukommen lassen will,
dann muss ich natürlich irgendwie eine Liste abarbeiten können,
wo draufsteht, ah, dem muss ich eine Mail schicken,
dem muss ich eine Mail schicken,
dem muss ich eine Mail schicken.
Also das sind alle Leute,
die sich für meine Änderungen interessieren
Vielleicht so ein bisschen Follower bei Twitter oder so.
Macht ihr sowas vielleicht? Ja, also jeder,
der bei Twitter gefollowt wird, der hat dann so eine Liste,
wo entsprechend viele Leute drin sind.
Und immer wenn ein neuer Tweet kommt, dann wird das rausgeschickt an die Leute.
So ähnlich kann man sich das vorstellen. Okay,
nun, das ist quasi ein neuer Mensch,
will meinen Tweets followen, wenn man so will, auf Neudeutsch.
Und ja, das muss jetzt aufgerufen werden,
wenn ich tatsächlich sage, jetzt ist ein Zeitpunkt gekommen,
wo ich meinen Leuten Bescheid sagen will.
Gut. Ich glaube, das ist schon alles.
Oder ich gucke mal kurz, ob wir irgendwas vergessen haben.
Wir können uns ja nochmal über, ja,
Sichtbarkeiten Gedanken machen. Also Attribute machen wir immer private.
Ich glaube, da schreibt man eine OML so ein Minuszeichen
Wie ist das mit dieser Methode, registriere?
Sollte die Privatprotected oder Public sein? Also ich fahre vielleicht
mal das andere Leute. Also privat würde ja heißen,
nur innerhalb der Klasse selber aufrufbar. Das heißt,
ich könnte nur mich selber registrieren als Beobachter, das wäre irgendwie sehr komisch.
Also an mir selbst. Ich interessiere mich für mich selbst.
Es hält sich schon Grenzen, das Interesse bei mir persönlich.
Oder ich sage protected, dann können nur erbende Klassen sich registrieren.
Oder ich sage, auch andere Klassen können sich registrieren.
Ja, was wäre denn da jetzt sinnvoll beim Registrieren?
Dahinten meldet sich jemand
Richtig. Sehr schön. Es sollen sich ja andere registrieren
, sehr gut. Das muss also Public sein, manchmal
ein Plus davor. Wie ist es mit Informiere über Änderungen
? Also wenn wir das Public machen würden,
dann würde das zum Beispiel heißen, du könntest anstoßen,
dass alle meine Follower über meinen aktuellen Zustand informiert werden.
Also ist das so in Ordnung,
dass du das anstößt oder sollte ich das nicht lieber selber
anstoßen?
Andere Vorschläge, da
Protected, damit es die Erben machen können. Denn in
unserem Fall ist der Erbe ja Sheet. Also dieses Unschuldige,
oh, was für Protected steht, glaube ich.
Heißt also Sheet darf sagen, jetzt sollen meine Beobachter benachrichtigt werden.
Während zum Beispiel Excel das nicht sagen darf,
dass wir irgendwie auch irgendwie leicht merkwürdig,
woher soll er wissen, wann was Interessantes passiert ist.
Das finde ich unheimlich spannend, dass hier also
alle drei Sichtbarkeitsmodifikatoren in einer realen Klasse vorkommen.
Vielleicht auch für die Klausur relevant, ja.
Toll, kann man dann die Sichtbarkeitsmodifikatoren abfragen. Okay,
jetzt haben wir hier Ein Parameter vom Typ Beobachter,
kann ich das mal irgendwie so entzerren, dass sie alle alles seht?
Ich kann doch eigentlich im Prinzip das mal so ein bisschen nach links machen.
Nein, das wird ein Pfeil, ich wollte keinen Pfeil zeichnen.
Das mache ich immer wieder, ich wollte es doch nur verschieben.
Schieben wir uns mal so ein bisschen nach links.
Das kann auch alles so ein bisschen nach links geschoben werden.
Und das natürlich dann auch und so. Dann wird es
doch so ein bisschen das alle alles sehen können, ja.
Ich hoffe mal, jetzt können alle alles sehen.
Ja. So. Warum habe ich das gemacht?
Wollen wir diesen Parameter nicht sehen konnte? Also,
wir haben einen Parameter vom Typ Beobachter und wir haben hier
eine Liste von Beobachtern
Ist das im Diagramm schon irgendwie ausgedrückt durch Pfeile oder fehlen da
jetzt irgendwelche Pfeile? Das sind Pfeile, sollen ja immer
Abhängigkeiten ausdrücken. Was ist denn das für eine Abhängigkeit,
wenn ich da so eine Liste von Beobachtern habe?
Ist das eine Vererbungsbeziehung oder immer dieselben Leute?
Also, das ist auch eine tolle mündliche Prüfungsfrage eigentlich.
In der Klasse A taucht der Typ B auf bei
den Exemplarvariablen Bs in diesem Fall das.
Und das ist Klasse A, das ist Klasse B.
Welche Beziehung ist das? Welchen Pfeil muss ich da einzeichnen
? Ist das eine Vererbungsbeziehung zum Beispiel oder wie nennt man
diese Art von Beziehung
Also wenn ihr jemals eine mündliche Prüfung bei hier Anwesenden macht,
dann solltet ihr sowas beantworten können.
Ja. Ah, eine strukturelle Abhängigkeit. Was nehmen wir
denn mal? Diesen Durchgezogenen hier? Gut. Also es
ist vor allem keine Vererbung, das ist mir wichtig.
Es ist eine Benutztbeziehung und strukturell abhängig ist noch ein Bonuspunkt für dich.
Sehr schön. Wenn es jetzt nur der Parameter wäre,
dann hätten wir den wahrscheinlich gestrichelt gemacht,
aber so der Experte bin ich da auch immer nicht.
Gut. Ja. Das finde ich ganz spannend. Also,
wir haben hier auf der ganz konkreten Werkzeugebene Haben wir eine
Abhängigkeit von Excel nach Sheet? Und wir haben explizit gesagt,
wir wollen keine Abhängigkeit in die Gegenrichtung haben.
Wir wollen das Sheet verstehen können, ohne Excel verstehen zu können.
Aber natürlich muss diese Abhängigkeit dann irgendwo anders sein. Ja,
wenn dieses Sheet auf irgendeine magische Art und Weise dem Excel Bescheid sagen soll,
dann muss es ja irgendwo diesen Weg zurückgeben.
Und dieser Weg zurück, den seht ihr genau hier.
Der ist also dann hier oben, ja,
quasi so ein bisschen wegversteckt in diesem Entwurfsmuster.
Aber das Tolle ist eben, dass der Typ Excel
jetzt nicht mehr in der Klasse Sheet auftauchte.
Was heißt nicht mehr? Vorher war das ja,
glaube ich, auch nicht so.
Woher hatten wir hier
irgendwelche Abhängigkeiten
Okay, wir haben das also auf eine abstrakte,
auf ein abstrakteres Niveau rum und deswegen ist das jetzt für das Verständnis kein Problem mehr.
Jedenfalls diskutiert man das so. Ich finde das aber auch
, ich sehe das genauso. Gut, fehlt jetzt noch
irgendwas. Also wir haben jetzt hier eine Interface,
dieses Interface wird benutzt an dieser Stelle,
es wird implementiert an dieser Stelle.
Jetzt ist es so, es gibt in Java zwei Interfaces
ohne Operation drin, aber die sind relativ selten.
Da gibt es Clonable und Serializable, das war es dann,
glaube ich, auch schon.
Also sollte ein Interface-Beobachter
auch irgendwelche Operationen definieren
Denn die Frage ist ja ansonsten,
wenn ich jetzt hier diese Liste von Beobachtern habe,
was kann ich denn Sinnvolles mit denen tun?
Also wenn du überhaupt keine Operationen definieren,
kann ich Equal Hashcott und To String auf den aufrufen.
Das ist ja irgendwie nicht so spannend. Was machen wir denn jetzt?
Ja. Richtig. Und ich nenne es jetzt mal nicht registrieren,
weil wir schon eine andere Methode hatten, die so heißt.
Ich nenne es immer ganz gerne, reagiere auf Änderungen,
Verarbeiteränderungen, wäre genauso okay gewesen.
Nutus ist ja jetzt nur eine Benennung.
Bitte nennt es in der Übung nicht genauso wie ich,
das wäre irgendwie langweilig. Also nehmt Namen,
die für euch
irgendwie Sinn ergeben
Ja. Achso, und ein Rückkauftyp braucht es, glaube ich,
nicht. So. Das ist jetzt noch irgendwie halbwegs verständlich.
Ich hoffe ja. Gut. Was glaubt ihr,
passiert in dieser Methode, informiere über Änderungen?
Also dieses Sheet sagt, hier ist was Interessantes passiert,
ich stehe jetzt irgendwie woanders. Ich will jetzt
meinen Beobachtern Bescheid geben und ich kenne ja meine Beobachter,
die stehen ja alle in dieser Liste drin.
Was könnte Sinnvolles jetzt in dieser Methode, informiere über Änderungen
passieren? Sehr gut, du hast gesagt,
wir gehen die Liste aller Beobachter durch und rufen auf jedem
Reagierer auf Änderungen auf.
Genau, genau das machen wir
Gut. Können wir jetzt in diesem UML-Ton noch irgendwas machen?
Bevor wir uns an die Implementation sagen, ich glaube nicht.
Das heißt, ich speichere das jetzt einmal.
Gehen wir mal, habe ich irgendwo einen Desktop,
hier ist er, dass ich es nicht vergesse,
nennen wir das mal Beobachter, zack.
Und dann können wir im Prinzip anfangen zu implementieren,
ja.
Gute Frage
Sehr gute Frage. Also die Frage war, warum beobachtet Excel?
Denn Excel muss dann ja quasi den Baconifier dann Bescheid sagen,
dass sich was getan hat. Und es muss der Statusland
beschert sagen, dass sich was getan hat.
Alternativ könnte man sich doch auch vorstellen, dass der Magnefier
direkt Beobachter ist und dass die Statusleien direkt Beobachter ist.
Und dann wird es entsprechend so verdrahtet. Hätte man auch
machen können. Es gibt Leute, die finden das eine besondere toll.
Die anderen sagen, nein, das finden wir besonders toll.
Ich wurde einfach mal in den Entwurfsregeln nachgucken,
ob dazu was Konkretes steht. Möglicherweise sind die nicht,
gehen die nicht so sehr ins Detail, um das zu verbieten.
Weiß ich nicht. Ich finde die Lösung auch gut,
die du vorgeschlagen hast. Aber wir machen es jetzt
so.
Okay, aber das ist schon sehr richtig erkannt,
wenn das Excel dann mitkriegt, es hat sich was getan,
dann muss es natürlich das irgendwie weiterdelegieren an Magnefire und Statusland.
Das hast du völlig richtig erkannt. Gut, dann würde
ich sagen, bauen wir doch erstmal diese beiden Typen.
Vielleicht fangen wir mit diesem Interface an, das ist ja relativ einfach.
Vielleicht machen wir dafür einfach mal ein neues Paket,
einfach weil es geht. New Package. Nennen wir das
doch mal vielleicht einfach Observer, mir fällt gerade nichts Schöneres ein.
So, und da tun wir jetzt mal ein neues Interface
rein,
das nennen wir Beobachter
Okay. Und da haben wir gesagt,
die Methode soll heißen, reagiere auf Änderung.
So. Und ob man da jetzt A oder AE schreibt,
ich weiß nicht, ob das in Java noch relevant ist,
es kann sein, dass euch irgendwelche Übungsgruppenleute anmeckern deswegen.
Dann nehmt einfach AE, dann erspart ihr euch die Diskussion.
Okay, das ist schon das ganze Interface, oder?
Ja, das ist das ganze Interface.
Und dann machen wir jetzt das Beobachtbare. Neue Klasse.
Beobachtbar. Sehr schön. Dann hatten wir gesagt,
wir wollen eine Liste haben von Beobachtern
Dann machen wir mal einen Konstruktor, kann ich das so einigermaßen schneller hinkriegen?
Ja, wenn mein Rechner schneller wäre, würde das gehen.
Machen wir eine Arraylist, oder? Das ist immer so
die Standardliste. So. Ach so. Ja,
das ist die richtige Liste, die wir nicht haben.
Okay. Und vielleicht einfach, damit es noch klar ist,
durch den Element-Typ hier nochmal rein.
Muss man ja seit Java 7 nicht mehr unbedingt machen.
Okay. Haben wir also diese Liste?
Was brauchen wir als nächstes, diese registriere Methode?
Regestriere Beobachter
So. Ja, mich mal auf Vollbild, das ein bisschen mehr sieht.
Und dann tun wir den einfach in die Liste dazu.
Also alle Beobachter, add neuer Beobachter. So. Das sieht
doch auch gut aus. Alles ist auf Public gesetzt.
Ja, also wir wollen... Also erstmal muss die Klasse ja
abstrakt sein, ne? Dann kann man sich vorstellen,
es reicht, wenn der Konstruktor protected ist.
Das ist sonst vielleicht ein bisschen verwirrend,
wenn an einer abstrakten Klasse, die ja sowieso,
wo der Konstruktor sowieso nur von den Erben aufrufen kann,
dann verwirrt es, glaube ich, nur,
wenn der Konstruktor public ist.
Der reicht also protected. Aber das registrierende muss ja tatsächlich
Public sein. Darauf hatten wir uns ja geeinigt.
Das war ja hier mit dem Plus Plus heißt der Public.
Und dann noch das, wie haben wir es genannt,
informiere Überänderungen. So irgendwie. Genau,
und da hat er ja schon der Herr gesagt,
wie es geht, aber vielleicht frage ich einfach nochmal in die Runde,
ob sich noch jemand anderes erinnert oder in die hat,
was sich da jetzt reinschreiben muss.
Hat er heute auch schon was gesagt,
du hattest auch schon ganz viel gesagt.
Ja, die Dame?
So. Genau, das ist so die Standardimplementation. Also das ist
meine Liste von Beobachtern. Ich will über alle rüber iterieren,
das ist der Elementtyp und so nenne ich in der Schleife
den jeweiligen Beobachter, den ich an der Hand habe.
Das ist ja ein völlig beliebig gewählter Name. Und an dem
rufe ich dann die Methode, reagiere auf Änderungen auf.
Das heißt zum Beispiel, wenn die Liste leer ist,
passiert gar nichts. Ich brauche kein zusätzliches iF. Also manchmal
setzen die Leute das auch um, nicht mit einer Liste,
sondern einfach mit einer Beobachterreferenz, die neil sein kann,
dann muss man das da unten extra prüfen und so.
Ich finde das irgendwie ganz nett mit einer Liste,
dann muss man nicht den Spezialfall abfragen,
dass die Liste leer ist.
Es geht ja auch mit einer leeren Liste,
die VE schlafen,
passiert einfach nichts.
Ich glaube, das ist schon das ganze Grundgerüst,
was wir brauchen, oder?
Haben wir irgendwas vergessen? Gucken wir einmal ganz kurz.
Wir haben die Liste, wir haben die Methode,
wir haben die Methode, nee, sieht gut aus.
Okay, was machen wir als nächstes? Vielleicht kümmern wir
uns mal um diesen Pfeil, dass also Sheet von beobachtbar erbt.
Also, wo ist die Klasse Sheet? Hier ist sie.
Und vor allem kommentiere ich mal als erstes diese Zeile aus.
Wir wollen ja nicht mehr diese Abhängigkeit haben.
Und ich nehme auch mal diesen Parameter weg.
Ich will nicht wissen, dass es diese Klasse Magnan Fire gibt.
Die Klasse Magnan Fire soll nirgendwo vorkommen in der Klasse Sheet.
Ich will komplett davon entkoppelt sein. Gut,
aber jetzt sage ich, ich bin also beobachtbar
Ah, muss ich importieren wahrscheinlich,
weil ich ein anderes Paket getan habe, ne?
Genau. So. Heute ist er zufrieden. Und jetzt ist natürlich die Frage,
an der Stelle, wo ich vorher hart gekodet habe,
naja, es hat sich was geändert,
dann setze ich mal den Text von dem Magney Fire.
Was muss ich denn da jetzt stattdessen tun?
Also ich bin jetzt gerade in dieser Klasse,
mein Zustand hat sich jetzt gerade geändert.
Was ist jetzt die logische Schlussfolgerung? Was muss ich jetzt
machen, damit dieser Zustand in die Welt geblasen wird?
Ah, der Herrn Blaune. Informiere Beänderung,
sehr gut. Ich will jetzt ja, dass die Beobachter
Bescheid bekommen
Informiere Überänderungen. Zack. Gut. Und ich bin der Meinung,
dass wir in der Klasse Sheet sonst nichts mehr machen müssen.
Ihr seht also an dieser Stelle, okay,
offenbar hat sich der Zustand auf eine interessante Art und Weise geändert,
sodass vielleicht andere darüber Bescheid wissen wollen,
aber wer das ist,
ist mir in dieser Stelle völlig egal.
Ja, das ist die Magie dieser Entkopplung.
Okay. Gut, was haben wir jetzt gemacht?
Wir haben also diesen Fall jetzt quasi implementiert.
Dann können wir uns ja nochmal diesen Pfeil implementieren.
Also, die Klasse Excel, die jetzt ja nicht mehr
diesen Parameter hier reinsteckt,
den habe ich ja gelöscht,
weg damit
Die soll jetzt ein Beobachter sein, Implements, Beobachter,
Implementsbeobachter, muss importiert werden, liegt ja in einem anderen Paket.
So. Und jetzt gibt es einen Compiler-Fehler. Warum? Wenn
man dieselben, keiner eine Idee, ja. Genau,
wir behaupten hier, wir würden das Interviews implementieren,
tun wir aber gar nicht.
Denn hier ist ja eine Operation drin,
reagiere auf Änderungen und die gibt es ja in Excel noch gar nicht.
Da sage ich also wieder Steuerung 1,
at unimplemented methods,
Da wird es jetzt irgendwo unten gelandet sein. Hier. Und alles,
was ich jetzt hier mal mache, ist zu sagen,
vielleicht irgendwie, dass man mal was sieht.
Ja, ist für Smart Printline. Ich wurde benachrichtigt oder so.
Wir gucken dann einfach mal, dass diese, dass das tatsächlich passiert.
Ich gehe natürlich davon aus, dass das nicht passieren wird,
weil sonst wäre diese Methode vor dieser Herangehensweise wahrscheinlich ein bisschen sinnlos.
Ich starte jetzt einfach mal das System und wir gucken mal,
ob diese Meldung erscheint. Und ich gehe mal davon aus,
dass sie es nicht tut. Also ich würde jetzt erwarten,
dass ich jedes Mal, wenn ich hier durch die Gegend klicke,
das jetzt hier unten in meiner Konsole, die würde dann automatisch aufgehen,
aber ich kann sie auch ruhig anklicken explizit.
Das jetzt hier irgendwie stehen würde,
ich wurde benachrichtigt,
steht aber
gar nicht
Hä? Wie kann das denn sein? Ich habe doch
diese wunderbare Klassendiagramm. Ich hatte auch diesen Pfeil so wunderbar
umgesetzt. Ich habe doch diesen Fall so Wunderhorn gesetzt,
der ist sowieso umgesetzt, einfach durch diese Abhängigkeit.
Ich habe doch jetzt das Klassendiagramm komplett umgesetzt.
Was ist denn jetzt das Problem? Warum werde ich
nicht benachrichtigt? Ich habe gesagt, alle Beobachter sollen benachrichtigt
werden und Excel implementiert doch dieses Interface-Beobachter.
Immer dieselben Leute. Die Dame vielleicht nochmal?
Es wurde noch kein Beobachter registriert,
Es ist tatsächlich der Fall eingetreten, dass in dieser Methode über eine leere Liste iteriert wurde.
Sehr schön. In der Liste steht kein Beobachter drin.
Das ist ja hier eine reine Typinformation. List-Beobachter heißt ja nicht,
hey, liebes Java, stopft da mal alle Klassen rein,
die dieses Interface implementieren oder so.
Das würde irgendwie wenig Sinn ergeben. Also wenn ich diese Methode registriere,
nicht aufrufe, dann wird da nichts passieren und damit ihr mir das wirklich glaubt,
hier laufen auch noch mehrere Instanzen von dem System,
das ist wahrscheinlich auch nicht so schlau,
hat damit aber nichts zu tun.
Wenn ich mal in dem Beobachter hingehe und zum Beispiel sage, hey,
diese Methode registriere Beobachter, wo wird die eigentlich aufgerufen?
Soll ich einfach Steuerung Althaar? Und dann würde ich
mir sagen, Tja, die wird von niemandem aufgerufen.
Ansonsten könnt ihr das überhaupt sehen. Ja, ansonsten würde
jetzt hier unten stehen, wo die Methode aufgerufen wird,
aber hier steht nichts.
Ja, wo würden wir die denn jetzt sinnvollerweise aufrufen?
Wer soll diese Methode aufrufen? Wo soll ich den Code
hinschreiben, registriere und dann einen Beobachter übergeben?
Wer ist der Beobachter? Vielleicht registriert man sich einfach selber.
Meistens ist es ja so, wenn ihr irgendwo ein Zeitschrift,
ein Abo oder haben wir und sagt, hey,
ich will benachrichtigt werden, ich will ein Abo haben.
Wer ist dieser Ich? In der Klasse Fred gibt es
ja nicht
Ja. In der Klasse Excel, richtig. Also
wir gehen in die Klasse Excel und überlegen jetzt mal,
wo wäre diese Registrierung sinnvoll?
Wahrscheinlich ist es fast egal, oder irgendwie in dem Konstruktor.
Machen wir es doch mal ganz unten im Konstruktor.
Sagen wir also, liebes Sheet, registriere Beobachter.
Da ist sie. Das ist ja die geerbte Methode,
die steht dann da natürlich auch an der Schnittstelle zur Verfügung.
Was übergebe ich denn jetzt als Beobachter?
Ich will ja sagen, ich bin der Beobachter.
Solche Zereien schreiben, ich, geht das?
Oder was schreibt man in Schava stattdessen
Ja. This, genau. Das ist ja vielleicht auch
spannend. Da gehe ich noch mal ganz kurz rein.
Und wir können ja mal hier sagen,
neuer Beobachter hat sich gerade registriert oder so.
Das ist jetzt nicht zum Debuggen. Letzte Woche hatte ich
dieses Schüsselreportern so ein bisschen als Debugging-Hilfe genommen,
sondern einfach nur zum Verstehen, hey,
wann passiert da eigentlich was,
wie oft wird diese Methode aufgerufen und so weiter.
Stark und das System
nochmal neu
Oh, guck mal. Der Konstruktor von Excel ist durchgelaufen und
am Ende hat er dieses registriere Beobachter aufgerufen und tatsächlich.
Das ist der Paketname, das ist der Klassenname und das
ist einfach nur so ein blöder Hashcoach.
Hat sich gerade registriert. Das heißt also, jetzt ist
ein Beobachter in dieser Liste drin und mehr werden da auch nicht dazukommen.
Es gibt, wir haben ja nirgendwo anders diese Code hingeschrieben, die registriere Beobachter. Okay,
und wenn ich jetzt hier irgendwo hinklicke, ich wurde benachrichtigt,
es stand sogar mehrfach, das ist ja interessant,
da sind wieder irgendwelche Swing-Eigenschaften, die ich immer so,
aber jetzt steht es da nur einmal.
Ich glaube, das hat mit dem Hausklick zu tun,
wenn ich jetzt hier klicke
Habe ich zweimal geklickt. Ich weiß es nicht.
Ist ja auch nicht schlimm, wenn man mehrfach klickt.
Ja. Aber seht ihr jedes Mal,
wenn ich einen Kaso bewege, passiert diese Benachrichtigung.
Das ist doch super. Okay, dann kill ich mal kurz das System.
Was wollen wir denn jetzt in Excel tatsächlich machen?
Das ist jetzt ja hier so eine Dummy-Ausgabe. Ich will
ja nicht, dass auf die Konsole was geschrieben wird.
Was soll denn jetzt tatsächlich passieren? Also nochmal zurück in
das Diagramm. Sheet stellt fest, es hat sich was getan,
der Benutzer ist jetzt irgendwo anders in meinem Sheet,
das will ich irgendwie meinen Beobachtern sagen.
Dann wurde durch diese Liste gegangen, jetzt wurde diese Reagiere
auf Änderung aufgerufen, jetzt bin ich gerade hier.
Was soll ich jetzt
sinnvollerweise tun
Keiner eine Idee. Genau,
wir müssen jetzt irgendwie an dem Meghan eine Vereinermethode aufrufen,
dass da jetzt was anderes angezeigt werden soll.
Jetzt hatte ich die Zeile schon gelöscht,
die vorhin mal irgendwann dafür gesorgt hatte. Ist kein Problem
. Wir haben ja die Autovervollständigung, also Meghany Fire.
Was kann man denn mit dem so alles machen?
Seht ihr da irgendeine Methode, die euch sinnvoll erscheint?
Die dafür sorgt, dass da jetzt eingetragen wird,
was gerade in der Zelle drinsteht
Du kannst auch einfach in den Raum rufen,
wenn ihr euch nicht traut, euch zu melden.
Sehr gut, Settext ist richtig. Okay, und welcher Checks
soll das sein? Oh, wo kriege ich den denn jetzt hier?
Gucken wir noch mal ganz kurz ins OML-Diagramm. Also,
Excel Wilde Magnefire sagen, hier ist dein neuer Text,
aber was ist denn der neue Text?
Wo kriege ich den denn jetzt her? Ja. Der müsste
irgendwie im Sheet stehen. Und damit die Zeile nicht zu kompliziert wird,
lasse ich das ruhig mal so und schreibe mal darüber,
Sheet und gucken mal, ob wir da irgendwas...
Ach, wisst ihr was? Vielleicht habt ihr gerade
gar nicht alle Methoden gesehen. Ich scrolle das mal so
ein bisschen hoch, nicht, dass es daran scheitert.
Das wäre ja blöd. Ich hoffe, es war kein Beamer-Problem.
Gibt es hier irgendeine Methode, die euch sinnvoll erscheint in diesem Zusammenhang?
Es ist schon wieder, dass Eclipse so schlau ist oder es ist Zufall.
Ich weiß es nicht. Ganz oben habe ich gehört.
Gets elected text, das klingt doch gut.
Zack. Ja, ich kann also das Sheet fragen,
welcher Text ist jetzt gerade selektiert?
Die Information hole ich mir. Und dann stecke ich sie
in den Macney Fire rein. Dann gucken wir mal kurz
, ob das jetzt funktioniert
Also irgendwelche wie Hello World und dann schauen wir mal,
ich gehe jetzt mit dem Curse nach oben.
Ach, ihr seht gar nichts. Ich muss immer daran denken,
dass ihr ja gar nichts sehen könnt durch diesen belöten Beamer.
So, jetzt mache ich den Curse nach oben.
Wollen wir uns selber einen Applaus geben, wenn es klappt?
Ich bin dafür. Also wenn es klappt, bitte ein kleiner Applaus.
Okay, ja, es war ein kleiner Applaus, das war okay.
Gut. Okay, wir haben ja noch fünf Minuten.
Dann hatten wir ja gesagt, wenn das funktioniert,
auch jetzt habe ich das System geschlossen, warum eigentlich,
dann wäre es doch auch schön,
wenn man unten in dieser Statuszeile sehen würde,
in welcher Ja, zähle ich gerade irgendwie bin.
Das wäre doch irgendwie ganz nett. Ich weiß gar nicht,
ob wir das letztes Jahr hinbekommen haben. Ich glaube,
es war so eine blöde Hilfslösung. Wir gucken mal.
Irgendwie sah das letztes Jahr nicht so schön aus,
aber wir haben ja fünf Minuten, das schaffen wir vielleicht noch.
Okay, also ändert sich dann an dieser Verdrahtung irgendwas?
Wir haben ja momentan die Verdrahtung, Excel kriegt Bescheid,
wenn ein Schiedsrichter was tut. Das ist ja wunderbar.
Und momentan sagen wir, Excel, hey, liebes Sheet,
gib mir den neuen Text und den neuen Text,
geben wir dann den Backney Fire.
Was muss ich jetzt noch machen? Naja,
ich muss eben irgendwie noch dem Sheet sagen, hey,
gib mir doch mal die aktuelle Position oder irgendwie sowas.
Und muss daraus dann einen schönen String zusammenbasteln und den in
diese Statusline reinstecken. Macht das so halbwegs Sinn?
Ich hoffe schon
Das heißt, wir gucken erst mal wieder, kann man
denn dieses Sheet überhaupt fragen, wo wir gerade sind?
Ist das irgendwie möglich? Warum versuchen wir es doch einfach
mal, Sheet? Was gibt es denn da so?
Ja, das sieht doch eigentlich... Genau,
das selected rose elected color, ne?
Dann nehme ich doch einmal das, nenne das vielleicht einfach mal Row.
Dann wissen wir schon mal, in welcher Zeile wir sind.
Dann hat man noch Callum, Selected Colum, genau.
Das sind jetzt ja zwei Zahlen. Will ich jetzt
irgendwelche Zahlen da unten stehen haben
Nee. Also ich will quasi die Spalte,
also das Cullem, will ich als Buchstaben haben.
Und die Zeile will ich dahinter als Zahl haben.
Tja, ich erinnere mich jetzt wieder an diesen Hack,
den wir letztes Jahr gemacht hatten.
Wir hatten also gesagt, wir hatten gesagt, wir nehmen
dieses Cullem und addieren da mal den Buchstaben A drauf.
Ich glaube, so hatten wir das gemacht. Und dann hatten wir gesagt,
dann müssen wir das noch in den Shark casten,
weil es sonst ein Int ist.
Und das hatten wir, glaube ich,
genannt,
Cullem as Char
Versteht das jeder? Also wenn Tallum den Wert null hat,
dann wird diese Variante den Wert A haben.
Und wenn Karlum den Wert 1 hat, wird es den
Wert B haben. Ich hoffe, das ist sonst,
guckt euch mal Unicorn-Tabellen an, dann ist es hoffentlich klar.
Und was muss ich jetzt machen? Ich will also
dieses A und diese zwölf hier aneinander kleben.
Ja. Aber der Magnify ist ja oben,
wir reden jetzt, glaube ich, über diese Statuszeile.
Wollen wir mal gucken. Genau,
wir wissen ja eigentlich gar nicht, was die Schnittstelle von
diesem Statusline ist
Zieht ihr da euren alten Bekannten? Ja. Settext,
guck mal, das hat nämlich auch einen Settext,
das habe ich extra schön konsistent gemacht.
Und was stecke ich da jetzt als neuen Text rein?
Ja. Ja. Ja. Plus Row, ne? Ja,
ich, ach, schlach, der Compiler merkt das schade.
Ich hatte gehofft, dass er es nicht merkt.
Warum gibt es hier
ein Problem
Aha, wir übergeben einen Int. Wir haben ja hier
diesen Char und das ist ein Int und ach ja,
wie kriegen wir den?
Sieht jemand das Problem? Wir idieren einen Char,
ein Int und das wird wieder ein Int.
Also dieses Plus ist keine Streamcon-Katellation. Ich will ja
eigentlich Streamcon-Katellation haben. Noch einen leeren Stream dazu bauen.
So. Dazwischen, ach ja, kann man auch machen.
Ist eigentlich egal. Vielleicht ist es irgendwie logischer,
wenn es dazwischen ist. So. Mal gucken,
ob das jetzt irgendwie funktioniert. Und ihr seht schon,
das ist irgendwie nicht so hübsch. Aber mal gucken.
Ah, könnt ihr das erkennen?
Ja. Das funktioniert
Ja, also ich habe den Eindruck, er macht das Richtige.
Okay, und dann gucken wir noch mal ganz kurz,
ob wir das nicht ein bisschen hübscher hinkriegen, denn ich erinnere mich,
ich habe ja extra noch mal das Video vom letzten Jahr geguckt.
Wir können einfach mal sagen, das ist zwar wunderbar,
das ist dieses Select Round Select Gets,
Elector Drone Gets, Selected Columb gibt,
aber können wir nicht noch eine weitere Methode zur Verfügung stellen,
die mir das irgendwie direkt als einen String zurückgibt,
also Public String, Get selected Columb Name,
hatten wir das, glaube ich, genannt,
denn sowas gibt es auch schon an diesem internen Swing-Typ.
Ich glaube, da gibt es sowas wie, guck mal
, Get Columb Name. Und den muss ich jetzt
nur noch sagen, für welche Spalte ich mich interessiere,
das ist ja einfach nur Get selected Columb,
Ist das irgendwie so halbwegs nachvollziehbar? Jetzt mit so ein
bisschen Zeittalk im Nacken. Also ich kann einer Tabelle sagen,
ich kann im Prinzip jeden beliebigen Int übergeben und sagen,
wie heißt denn die Spalte, zu der dieser Int gehört?
Und ich interessiere mich natürlich für die aktuelle Spalte.
Wenn euch das zu kryptisch ist, kann ich natürlich auch sagen,
Int Colum ist gleich, dann dieser Ausdruck, zack,
das ist ja die, wo ich gerade bin.
Und dann kann ich das hier so reinstecken, zack.
Und dann kann ich an dieser Stelle einfach sagen,
diesen ganzen Hexenkram brauche ich nicht mehr.
Dann sage ich doch mal direkt so.
Und dann heißt das einfach nur noch,
und dann nehmen wir
die Flagge um
Habe ich die anders genannt? Was ist wieder hier von mir?
Habe ich mich irgendwie vertippt? Get selected, gerade fehlt
das N. So. Der Name ist jetzt natürlich nicht so schön,
da nennen wir das auch mal Column Name, oder?
Selbstverständlich. Guck mal, das liest sich doch viel schöner.
Column Name plus Road, das will ich doch haben,
oder? Ich will nicht Charles und Ins addieren und die
auf Chark casten und dann leeren String dazwischen kleben.
Das ist irgendwie nicht wirklich im Sinne des Erfinders.
Und dann schauen wir jetzt nochmal. Achso,
ihr seht nicht, in welcher Spalte ich tatsächlich bin.
Wir haben ja so C.de,
das ist also alles richtig
Okay, dann würde ich sagen, gehen wir doch mal zusammenfassend noch mal kurz auf das OML-Diaagramm.
Ihr habt jetzt also gesehen, wie man Abhängigkeiten,
die man nicht haben will, weil sie irgendwie in beide Richtungen gehen.
Meistens ist das ja das Problem oder innerhalb einer Schicht,
wie man die in diesem konkreten Fall rauskriegt,
indem man also die Rückwärtsbeziehung hochzieht in das Beobachtermuster rein.
Dann haben wir gesehen, was bedeutet es, beobachtbar zu sein. Das heißt,
ich kenne meine Beobachter,
ob man jetzt in der Liste steckt oder eine Menge oder sonst ist eigentlich völlig egal,
ich kann neue Beobachter registrieren, das sollte man nicht vergessen,
wenn ihr irgendwie den Effekt oder den Übungen, hey,
hatten wir den Effekt,
das hätte ich gar keine Beobachter,
dann habt ihr wahrscheinlich einfach vergessen,
diese Methode aufzurufen
Und diese Methode dient dazu, zu sagen, okay,
jetzt will ich wirklich meinen Beobachtern Bescheid geben,
dass sich was getan hat und was passiert da in einer Vorschlafe,
wird einfach nur diese Methode aufgerufen.
Und da kann dann passieren, was auch immer hierfür als sinnvoll
erachtet wird. Normalerweise wird dann an den Materialien gefragt,
was ist der aktuelle Zustand und dann wird das entsprechend verarbeitet
und andere Werkzeuge werden dann wieder angepasst.
Ja, vielen Dank,
bis nächste Woche