Was habe ich denn heute alles mit euch vor? Ach,
das ist ja alles noch Kram von vor drei Wochen.
Das brauchen wir auch nicht mehr. Das ist das Zirkus
Plus. Das ist alt. Gut. Ja,
heute ist Vorlesung 9. Ich weiß, das ist verwirrend,
weil die Vorlesung 7 gab es irgendwie zweimal auf Lecture to go.
Und das Thema ist Entwurfsmuster. Okay,
ich will heute vier Entwurfs, Entwurfsmuster mit euch machen.
Wir sehen nämlich die noch zusammen kriege.
Ich wollte einmal mit euch
die Fabrikmethode machen
Dann den Iterator, den Beobachter.
Und hoffentlich haben wir da noch Zeit, den Proxy.
Und ich habe da teilweise neue Projekte für vorbereitet und
eine ganz alte Sache habe ich noch ausgegraben.
Erinnert sich noch jemand an Bluetrail?
So die leicht nostalgische Gefühle kommen jetzt hoch.
Ich habe mal das Projekt aus Woche 12 ausgegraben,
fallen mir da eigentlich jedes Jahr dasselbe einfällt.
Und das bietet sich ganz gut an als Einstieg für
dieses Thema Entwurfsmuster. Also wir haben hier zwei Klassen,
Ganz viel läuft da jetzt noch nicht, weil das hier
sozusagen die Ausgangsversion ist. Und Link-Titel-Listen-Test. Und wir haben
diese Tests über Jahre gepflegt. Am Anfang waren das irgendwie 20,
dann waren es irgendwann 21, da waren es irgendwann 22.
Und wir mussten jedes Mal daran denken,
wenn wir hier irgendwie einen Test hinzufügen,
dass wir den dann kopierten und in die andere Testklasse mit reinnahmen.
Das hat nicht immer so hundertprozentig funktioniert. Und das ist ja irgendwie
ein bisschen blöd. Also kann man sich vielleicht überlegen,
kann man nicht irgendwie Gemeinsamkeiten aus diesen beiden Klassen
irgendwie mal wieder in eine abstrakte Oberklasse hochziehen.
Dafür wäre vielleicht ganz interessant zu wissen, was sind denn überhaupt die Unterschiede?
Und wir sind ja hier Linux fortgeschrittene Amateure. Wir gucken
mal ganz kurz, wo habe ich das Projekt hingespeichert?
Da ist es. So, und da wollte ich jetzt mal gucken,
welche Unterschiede gibt es eigentlich zwischen dieser Testklasse für die Ari-Titel-Liste und
dieser Testklasse für die Linktitel-Liste. Kann man einfach sagen,
gib mir mal das DIV,
also die Differenzen zwischen zwei Dateien.
HRE, Titel, Listen,
Test und Linktitel-Listen-Test
Und dann schauen wir mal, also das sind ja riesige Dateien,
bevor ich das jetzt verrate, lass uns mal ganz kurz angucken.
Also das ist schon ziemlich viel Code, ne?
Ich habe jetzt hier gar keine Zahlen nochmal aktiviert.
Warum eigentlich nicht? Das vergesse ich immer, wenn ich
Tree Unit inszeniere. Ja, wir sind schon bei 300,
400, also ungefähr 500 Zahlen Code.
Wurde man jetzt da vielleicht erwarten, dass da einiges verschieden ist?
Schauen wir mal. Oh, die Unterschiede passen auf eine Seite.
Das ist ja interessant, schauen wir mal. Okay,
also wir sind hier, sind wir im JavaDoc-Kommentar. Ja,
der eine Kommentar sagt halt, das ist für die RE-Titelliste,
der andere sagt, das ist für die Linktitelliste der Test.
Natürlich heißen die Klassen anders, deswegen steht hinter dem Public Class jeweils was anderes.
Der Konstruktor heißt wie die Klasse, deswegen unterscheidet sich das natürlich auch.
Und das eigentlich Spannende Es gibt also offenbar eine Methode,
die eine neue RAI-Titelliste zurückliefert, beziehungsweise eine neue Linktitel-Liste.
Wollen wir uns das einmal ganz kurz angucken.
Hier, da haben wir es schon.
Ja. Das ist also eigentlich der einzige echte Unterschied.
Der andere Unterschied ist nur, weil dann eben Konstruktoren heißt,
müssen wir die Klasse oder weil sich Kommentare darauf beziehen.
Ja, das heißt, wir könnten doch jetzt,
wir wissen ja, was eine abstrakte Klasse ist.
Wir könnten doch eigentlich fast den gesamten Code hochziehen in eine
abstrakte Klasse. Und nur noch diese Methode unterscheidet sich
dann in den konkreten Klassen
Das machen wir doch mal zusammen. Ich kopiere mir jetzt
mal hier sämtlichen Quelltext aus dem RI-Titel-Listen-Test.
Mach mal eine neue Klasse, die ist abstrakt.
Und nenne sie vielleicht mal Appstract-Titel-Listen-Test. So,
da kopiere ich jetzt mal ganz stumpf alles rein.
Und denke hoffentlich daran, dass ich jetzt alle Änderungen mache.
Ich gucke noch mal ganz kurz auf der Konsole.
Genau, Javadoc, Klassenname und Konstruktornahme.
Okay, Javadoc. Jay-Unit-Testklasse. Ich würde sagen,
vielleicht mal abstrakte Jay-Unit-Basis-Testklasse oder so
Für die beiden, ja, was auch immer,
ja, konkreten Klassen, egal.
So, dann heißt das hier natürlich nicht Airy-Titel-Listen-Test,
sondern App-Strike-Titel-Listen-Test. Und der Konstruktor muss natürlich genauso heißen.
App-Strike-Titel-Listen-Test. Okay. Gut, das ist also hier alles Code,
der für beide konkreten Klassen gleich ist, da,
da, da, da. Und jetzt hier unten,
ich bin jetzt ja in der abstrakten Oberklasse drin,
ja, was mache ich denn jetzt hier?
Eine Airy-Titel-Liste zurückziehen wäre ja irgendwie blöd.
Ich will ja nicht in beiden Fällen eine Airy-Titel-Liste haben als
Als zu fest in der Klasse. Was wäre denn jetzt hier sinnvoll,
in der abstrakten Klasse mit dieser Methode zu machen?
Ja. Die selber zu erzeugen. Du willst deine abstrakte Klasse erzeugen,
das ist ja, glaube ich, schwierig in Java.
Hat jemand noch eine andere Idee? Darm? Abstrakte Methoden, genau.
Wir machen die Methode einfach abstrakt. Ich sage also,
ich kann an dieser Stelle noch gar nicht wissen,
was die Methode mal machen wird
Vielleicht war das auch das, was der Herr I
meint und ich habe es nicht richtig verstanden.
Ich sage also, diese Testklassen können Listen erzeugen,
das sind irgendwie erstmal Titellist, das ist ja dieses abstrakte Interface.
Aber was da jetzt genau zurückgeliefert werden soll,
kann ich auf dieser abstrakten Ebene noch gar nicht sagen.
Ich glaube, es lässt sich jetzt noch nicht übersetzen.
Das ist so ein typischer Fehler. Sieht jemand den Fehler?
Kann man das lesen? Ist die Schrift groß genug?
Ich denke, ja. Keiner eine Idee
Ich lese es mal vor. Oder ich versuche es mal
zu übersetzen. Also diese Klasse ist nicht abstrakt und er
setzt nicht die abstrakte Methode der Zeugeliste aus ihrer Klasse selbst.
Ja, klar. Ja. Ich bin ein Gebot,
was das macht. Genau. Also ich habe zwar im Namen,
taucht zwar irgendwie dieser String Epstrack auf, aber das hat ja überhaupt keine Bedeutung.
Ich muss also sagen, dass sie abstrakt ist.
Sonst ist der Compiler nicht zufrieden. Gut. Okay,
habe ich jetzt also diese abstrakte Klasse hier oben und jetzt
kann ich ziemlich viel Code löschen und schauen wir mal
ganz kurz
Also das kann alles weg. Das brauchen wir noch.
Und dann muss ich natürlich sagen, dass ich jetzt von
dieser abstrakten Klasse, gibt es hier eigentlich auch Steuern-Lehrtaste?
Das versteht dann auch nicht in allen Kontexten.
Schade. Labstrack-Titel, Listen, Test.
Okay. Jetzt kommt so eine blöde Eigenschaft von BlueJA.
Ihr werdet jetzt sehen, wenn ich das hier zumache und übersetze.
Das BlueJay jetzt nicht mehr versteht, dass das eine Testklasse
ist, darum kümmern wir uns gleich.
Okay. Und dasselbe machen wir hier. Weg mit dem
Revolutantencode den Erbenbär von oben und sagen,
dass wir von Erben
Ja, ich hatte dazu irgendwann mal im Internet was gefunden.
Ich weiß nicht, ob das mittlerweile behoben ist,
aber der Quick-Fix war zu sagen,
ich mache einfach einen Test, der nichts Sinnvolles tut.
Aber Bluejoy ist sozusagen so, ja, blöd,
weiß nicht, ob das, ob das das richtige Wort ist.
Also sobald mindestens eine Klasse, der, Entschuldigung,
mindestens eine Methode mit diesem Test annotiert ist, versteht es,
dass es halt eine Testklasse sein soll.
Das heißt, wenn ich das jetzt nochmal neu übersetze,
ich kopiere mir das einmal in die Zwischenanlage für die
andere Klasse
Dann müsst ihr das hoffentlich wieder, ja, jetzt ist es wieder grün.
Ist so ein kleiner Hack, vielleicht findet ihr ja
eine schönere Lösung und dann kriegt ihr Snickers von mir.
So, genau. Okay, und jetzt kann man die Tests
wieder ausführen, natürlich schlagen die alle immer noch viel.
Ich habe ja nicht die eigentliche Funktionalität implementiert,
aber ich habe jetzt den Code eben nur noch einmal da.
Und wenn mir jetzt irgendwann auffällt, oh,
ich habe noch einen spannenden Testfall gefunden, Testfall Nummer 24 oder Nummer 25,
dann muss ich ihn nur noch in einer Klasse einfügen.
Ja. Das ist das, was ihr wisst,
hat nicht wahnsinnig herzlich
das ausgegeben
Das ist eine sehr gute Frage. Also warum ist das
hier nicht grün? Das weiß ich ehrlich gesagt nicht.
Vielleicht kannst du es herausfinden, ob wir nächste Woche sagen,
ich weiß es wirklich nicht. Okay, aber klar,
also es würde keinen Sinn machen, die jetzt auszuführen,
weil dann müsste der irgendwie ein Exemplar davon erzeugen.
Das ist wahrscheinlich der Grund. Gut. Jetzt habe ich
hier noch dieses wunderbare Tool mir mal installiert oder runtergeladen,
was ihr ja auch in den Übungen benutzt.
Hallo? Oh, da habe ich es,
habe ich nicht runtergeladen.
Oder ist es noch
ein Downloadsverzeichnis
Ja, da war's. Genau, und ich wollte das,
was wir gerade zusammen gemacht haben, in Blue Jay.
Nochmal ganz kurz mit euch zusammen malen.
Ich bin auch nicht besonders gut in diesem Tool,
nur falls müsst ihr mir ein bisschen helfen.
Also, wir haben eine, eine Klasse. Wie hieß
die? Appstract-Titelisten. Test hieß die. Ach so,
und diese Abstraktes kann man das nicht auch immer sagen?
Ist das vielleicht, wenn ich die erzeuge? Nee,
kann man nicht irgendwo sagen, dass sie abstrakt ist.
Ich glaube, das muss man einfach von Hand machen,
oder?
Irgendwie so
Okay. Und dann hatten wir hier einmal unseren Eric-Titel-Listen-Test.
Der war nicht abstrakt. Und dann hatten wir unseren Linked-Titel-Listen-Test
. So, und was sind jetzt die richtigen Pfeile?
In Harrels From, nehmen wir den mal, oder?
So. Interessante Layout-Wahl. Oh, nein, das wollte ich nicht.
Kann ich das irgendwie, ah, so gefällt es mir besser.
Gut. Und dann hatten wir noch eine Parallele Vererbungshierarchie dazu.
Das war quasi die Listen selber. Das war,
glaube ich,
ein Interface-Titel-Liste
Ach guck mal, hier hat er das jetzt gemacht.
Titel-Liste. Und dann hatte ich zwei Klassen, RAE-Titel,
RAE-Titel-Liste. Und Linked-Titel-Liste kriege ich das irgendwie, ja.
Und dann habe ich hier diese Implements-File und das sieht auch
nicht schlecht aus. Okay. Ja, nein.
So, ne? Okay. Und dann hatten wir noch
weitere Beziehungen
Denn wir haben ja hier in dem Abstract-Titel-Listen-Test, haben wir
ja diese abstrakte Methode, die diesen Typ Titelliste kennt.
Das ist vielleicht ganz spannend. Und dann haben wir noch
weitere Beziehungen, das wird gleich auch wieder spannend.
Also es gibt ja von hier eine Beziehung nach da,
machen wir das dann mal sinnvoll. Oder vielleicht,
wenn ich die hier austausche, so,
und dann irgendwie so, und das nach unten ziehe,
ich glaube, dann kriegt die Pfeile,
ohne dass sie sich überschneiden.
So, ne? Okay, das ist so ungefähr
unser Diagramm der relevanten Klassen
Und irgendwann werdet ihr so ein ähnliches Szenario nochmal feststellen,
würde irgendwie merken, oh, ich brauche genau das wieder.
Ich brauche irgendwie ein Exemplar in einer konkreten Klasse.
Es gibt sozusagen mehrere Geschwister von dieser konkreten Klasse und alle
implementieren dasselbe Interface in so einer ähnlich angeordneten Hierarchie.
Und irgendwann kommen dann halt Informatiker und stellen fest, hey,
das ist ja immer dasselbe Muster und erfinden dann noch so ein paar Vokabeln.
Also statt Titelliste sagen sie dann zum Beispiel,
das hier funktioniert mit dem Markieren,
sagen sie zum Beispiel Produkt,
das ist das,
was irgendwie erzeugt werden soll
Statt der konkreten Linktitellisse sagt man jetzt ganz abstrakt, konkretes Produkt.
A. Und hier sagt man dann zum Beispiel konkretes Produkt. B oder so. Okay,
und es gibt auch ähnliche Vokabeln hier von dem linken Teil,
die heißen dann einfach Klient oder so, das ist jetzt nicht so spannend.
Okay, also das Verwirrende bei den Entwurfsmustern,
wenn ihr sie das erste Mal seht,
ist wieder diese relativ abstrakten Namen,
die sich aber relativ automatisch daraus ergeben,
wenn ihr dieses Muster eben fünf bis zehn Mal gesehen habt und dann merkt,
ach, es geht gar nicht immer darum,
dass da irgendwelche Listen erzeugt werden.
Und es geht nicht immer darum,
dass da irgendwas anderes erzeugt wird.
Ich nenne das einfach mal
ganz allgemein Produkt
Ja. Okay, und dieses OML-Klassenjahr, was ich euch
jetzt hier hingemalt habe, ist eben das OMR-Klassendiagramm des Entwurfsmusters.
Fabrikmethode. Warum Fabrikmethode? Schauen wir uns noch mal
ganz kurz den Quelltext an, weil wir ja sagen,
ich habe in dieser ganzen Klasse nirgendwo einen New-Aufruf.
Ich erzeuge mir nicht selber ein Exemplar in einer ganz konkreten Klasse,
sondern ich verwende diese abstrakte Klasse, die dafür da ist,
eine dieser konkreten Listenklassen zu erzeugen oder zu instanzieren.
Und konkret werde ich dann eben erst in den Unterklassen und alles,
was in den Unterklassen passiert, ist,
dass da eben dieses New aufgerufen wird.
Also zum Beispiel hier, ach hier bin ich ja schon
ganz unten. Also in dieser Methode passiert nichts weiter
als eine Exemplarerzeugung
Und das ist im Prinzip das,
was das Ganze zu diesem speziellen Muster Fabrikmethode macht,
weil sonst könnte man ja auch einfach argumentieren, hey Fred,
ist das nicht einfach nur Schablon-Methode und eine Einschulmethode?
Also dieses Erzeugeliste ist ja im Prinzip eine Einschulmethode,
die hier dann irgendwie konkret realisiert wird.
Aber das Besondere ist eben, wofür benutzen wir hier diese
Schablon-Methode und Einschulmethode? Und wenn es nur um Objekterzongung geht,
dann spricht man eben von einer sogenannten Fabrikmethode.
Das ist schon alles. Das ist so nach meiner Meinung
eines der einfachsten Entwurfsmuster. Ja. Okay,
das kann ich auch irgendwo speichern, oder?
Das würde ich vielleicht, würde ich mich später nochmal darauf beziehen.
Das nennen wir mal Fabrikmethode.
Das hat geklappt. Und zumindest steht das da oben so.
Ja, auch gut. Ich glaube,
dann können wir Blue Jay gleich wieder schließen.
Das gibt mir ein gutes Gefühl. Weg damit. Okay,
das lasse ich nochmal offen vielleicht. Okay, Iterator,
nächstes Entwurfsmuster. Da habe ich hier ein ganz einfaches Mini-Projekt.
So vom Anspruch ist das eigentlich ähnlich wie das Projekt eben.
Nur, dass ich hier statt einer RAI-Titelliste einfach eine irre
Stringliste gebaut habe. Schauen wir uns nochmal ganz kurz an.
Woche 12, SE1 ist ja schon ein bisschen her
Was ist der Sinn dieser Klasse Stringlist? Ich will meine
eigene Erredes von Strings sozusagen implementieren. Ich habe also intern,
habe ich einen String-Array, das ist die Sonntags für String-Arrays,
das wisst ihr ja spätestens seit dem Programmiertektat, hoffentlich wieder.
Ich sage am Anfang, wir reichen hoffentlich zehn Einträge,
habe ich auch so eine Errede der Größe 10 mit zehn Mal Referenzen drin.
Ich habe eine Länge, weil es ist ja,
das ist ja nur die Kapazität,
10 ist nur die Kapazität und Länge ist die Katinalität,
die Unterscheidung kennt ihr auch noch hoffentlich.
Ich kann fragen, wie lang ist die Liste momentan?
Ich kann mir ein Element über den Index rausholen,
wird natürlich geprüft, ob es den Index überhaupt gibt.
Ich kann was hinzufügen, der Einfachheit halber,
nur am Ende, damit das Ding nicht überläuft,
muss ich immer zusehen,
dass genügend Kapazität da ist
Und ich kann was entfernen. Muss entfernen, gucken wir uns vielleicht später an.
Mal sehen, ob die Zeit dafür reicht. Okay,
und wie sieht jetzt so eine Klientenverwendung von dieser Liste aus?
Das war bis jetzt ja eigentlich nichts Spannendes.
Und das ist im Prinzip auch nichts Spannendes.
Ich erzeuge mich also so eine Stringlist. Am Anfang ist nichts
drin. Und dann füge ich mal fünf Wissenschaftler ein.
Juden, Einstein, Boah, Fineman und Oppenheimer.
Und jetzt will ich iterieren über diese Liste. Wie iteriert
man über eine Liste? Naja, wenn ich weiß,
wie lang die Liste ist, in diesem Fall fünf,
könnt ihr einfach über die Zahlen 0-1,
2, 3, 4 eine Vorschleife drüber laufen lassen.
Und die Liste immer fragen, gib mir doch mal
das Element an der Stelle.
0-1, 2, 3, 4. Das ist so,
wie soll man sagen, eine intbasierte Variante über eine Liste
zu iterieren
Ja. Wie ist das? Wenn man so eine Air-Relist von Java
hat, mache ich das einfach mal direkt hier unten.
Ich will mir eine Liste von Strings,
will ich haben, die nenne ich mal, egal,
oder was kann man statt sein,
das noch am Flower ist vielleicht?
Ah, ich kenne mich da überhaupt nicht aus.
Hoffentlich fahren wir gleich ein paar Blumennamen oder Animals.
Da muss ich mir nicht so blamieren. You are relist. Animals,
jetzt mach Steuernschiff, oh, das euch alles importiert.
Ach, List, List gibt es immer so viele,
ich will diese Liste haben.
So,
was will er noch
Achso, hier muss natürlich String stehen, Horst.
Ja. Okay, dann fügen wir da auch noch
ein paar Tiere ein, sagen wir mal.
Hallo? Nehmen wir einen Löwen, das heißt nicht Push ist das Ed.
Wir sind ja nicht, das ist ja kein Stack.
Aus nehmen wir noch einen Tiger vielleicht und eine Giraffe.
Schreibt man das überhaupt so? Jerath, nehmen wir lieber Cat. Okay. Okay,
und diese Variante von hier funktioniert natürlich genauso,
könnt ihr jetzt auch machen, aber was ja das Tolle ist,
seit 2004, Kann man ja auch schreiben.
Diese For-Each-Schleife-Eclipse ist da immer so unglaublich schlau.
Ja, genau, hat er alles für mich hingeschrieben.
Und dann kann ich hier einfach sagen, Stream finde ich nicht so schön.
Andere, ne? Ja. So. Ich führe das mal
aus, wenn aber alles klappt. Also die Konsole,
wo ist meine Konsole? Nix zu sehen, habe ich
es nicht wirklich ausgeführt. Da sind wir, genau,
ne? Hier war das ausgegeben.
Ja, was ist jetzt schöner? Also irgendwie gefällt mir
das deutlich besser, muss ich sagen.
Ich muss gar nicht über diese Position nachdenken. Ich muss
irgendwie nicht Angst haben, dass ich mich hierfür tue.
Manche Anfänger schreiben da vielleicht lieber 1, stand 0 hin.
Das ist immer so eine ganz beliebte Stelle,
schreibt man da jetzt kleiner oder kleiner gleich oder manche schreiben auch sogar größer oder so,
weil sie denken, vielleicht ist das ja das Abbruchkriterium.
Dann kann man sich hier immer fünf Minuten darüber streiten,
wie man jetzt am besten das I um einhöht.
Ja, da gibt es also auch verschiedene Parteien,
die einen wollen das bloß bloß davor schreiben, die anderen dahinter.
Und ich muss aufpassen, dass ich das I an allen
drei Stellen konsistent verwende. Wenn man sich diese Vorschleifen irgendwo
per Copy-Paste herholt, dann vergisst man das manchmal.
Dann steht hier irgendwie I und da steht dann irgendwie J oder so.
Okay, und das liest sich hier doch auch viel schöner
, oder
Also für jeden String Animal,
in der Sammlung Animals würde ich das Animal ausgeben.
Also da kann man ja eigentlich gar nichts mehr verkehrt machen.
Das fände ich nicht schlecht, wenn das für meine,
für meine Wissenschaftler auch gehen würde.
Ich probiere das einfach mal aus. Forestring Scientist,
in a cycle tists gebe ich den mal auf der Konsole aus.
Und jetzt beschwert sich Java. Mal gucken, was er jetzt sagt.
Can only iterate of and array or an instance of Java Lang Iterable.
Java Lang Iterable, das scheint irgendwas Besonderes zu sein.
Scheint auch so einen Zusammenhang zu geben,
zwischen dieser Spezialsyntax, die so im Sprachkern von Java Hart
definiert ist und einem Bibliothekstyp namens Java Lang Iterable
Uns hier mal angucken. Ich schreibe den einfach mal hin.
Ejo Rible X, einfach nur, damit es hier steht.
Und dann kann ich da mit F3 einfach reinsprengen.
Ah, das ist also dieser besondere Typ,
der irgendwas mit dieser For eat-Schlafe zu tun hat.
Aha. Was sagt denn der Java-Dokumentar? Implementing this interviews
and lows and object to be the target of the for each statement.
Das ist ja genau das, was wir wollen.
Machen wir gleich mal hier uns ein schönes Diagramm.
Also es gibt dieses Interface, Ejo Rible, okay.
Und es gibt nur eine einzige Methode, die heißt Iterator.
Gut, das nehmen wir erstmal in diese OMA-Diagon auf.
Also machen wir ein neues. Oh, was ist das
? Kenne ich nicht. Da, das will ich
Also ein Interface. Das heißt, Iteralo. Ja,
jetzt sind da noch diese Typen rahmen da mit dem Tee und so.
Soll ich das da hinschreiben? Ich schreibe es einfach mal hin. Okay,
und es hat noch eine einzige Methode, Iterator,
und die liefert zurück einen Iterator von Tee, wenn mich nicht alles täuscht,
schaue ich mir das noch mal ganz kurz an.
Ja, genau, das ist der Rückgabetyp. Dieses Tee,
irit, sollte euch nicht zu sehr irritieren, das ist
genau wie bei den Listen. Also ich kann sagen,
ich habe eine Liste von Strings und dann kann ich eben auch sagen,
ich kann über Strings iterieren, zum Beispiel bei einer Liste von Strings,
wenn bei einer Liste von Kunden könnte ich über Kunden iterieren.
Das ist einfach dasselbe Tee wie bei den Listen,
was ihr schon kennt
Okay, ich muss also irgendwie dieses Interface implementieren.
Das heißt, ich muss irgendwie eine Iterator-Methode einbauen,
in meine Klasse Stringlist, aber ich weiß ja gar nicht,
was ein Iterator ist, springe ich einfach wieder rein.
Was ist ein Iterator? Okay, das scheint schon ein
bisschen komplizierter zu sein. Wie viele Methoden hat er?
Drei. Das kriegen wir vielleicht gerade noch hin.
Okay, ich schreibe es erstmal wieder hin.
Es gibt also einen Interface-Sitterator. Iterator,
da stehe ich jetzt zwar im Quelltext eh,
aber das ist ja ein völlig beliebiger Name.
Und wir hatten also eine Methode Hays Next,
die liefert einen Bulien, wird kleingeschrieben.
Ja, Bulien
Next liefert einen Tee und Remove liefert überhaupt nichts zurück.
Okay. So, gibt es jetzt irgendwelche Beziehungen zwischen den
Typen? Ja, das kann ich ja direkt ableiten.
Also wenn hier der Typ Iterator auftaucht,
dann hängt natürlich dieser Typ von diesem Typ ab, ja.
Ja, ich will einen geraden Pfeil, so.
Okay, also eine Sammlung ist iterierbar bedeutet,
sie kann mir einen Iterator zurückliefern. Okay,
das ist ja immer noch irgendwie so ein bisschen abstrakt,
schauen wir uns mal an,
was jetzt hier in dem Java Doc
genau steht
Okay, heißen Next. Returns true if the iteration
has more elements. Okay, also dieser Iterator,
wenn ich irgendwie so eine Sammlung habe,
scheint dieser Iterator am Anfang irgendwie zu wissen, okay,
ich stehe am Anfang dieser Sammlung.
Habe ich dann noch mehr Elemente? Ja, da kommen noch
welche. Gut, da würde ich also Bulien erwarten.
Und wenn ich dann im Verlauf dieser Iteration immer weiter ans Ende komme,
irgendwann bin ich sozusagen, ja, habe ich das letzte Element geliefert.
Und dann würde ich sagen, jetzt gibt es keine Elemente mehr.
Die vor ihnen Schleife muss ja irgendwie wissen, wann sie aufhören soll.
Also diese Methode ist einfach dafür da,
um zu wissen, geht es noch weiter oder nicht?
Okay. Und hier kann ich den Iterator fragen,
auf welchem Element stehst du denn gerade?
Bist du gerade am Anfang irgendwo bei Newton? Ja,
oder ach ne, du bist nur bei Einstein oder du
bist bei Teppler oder Finan oder Offenheimer.
Also einfach, wo bist du denn gerade bei welchem Element
Gut. Und dieses Remove, ja, muss man
nicht unbedingt implementieren. Das ist so ein bisschen ungewöhnlich.
Normalerweise haben wir ja gelernt, wenn in einem Interface diese
drei Operationen stehen, dann muss ich die auch implementieren.
Wir müssen sie auch technisch implementieren. Aber dieser Vertrag,
hier erlaubt es uns, dass wir da einfach irgendeine Acception schmeißen.
Der Einfachheit habe, werden wir das gleich vielleicht einfach mal machen.
Okay, ja, dann überlegen wir uns mal ganz kurz,
dann schreiben wir das vielleicht auch mal in das OML-Deal am Rhein.
Also wir haben jetzt unsere klasse Stringlist.
Stringlist, die irgendwie dieses Interface implementiert
So. Und jetzt fehlen auch diese ganz konkrete Iteratorklasse.
Ich nenne die jetzt einfach mal Stringlist-Iterator, ganz kreativer Name.
Und die implementiert dann dieses Interface. Und dann können wir uns
da noch überlegen, welche Beziehung es zwischen diesen beiden Klassen gibt.
Also soll der Iterator diese Listenklasse kennen, soll die Listenklasse
den Iterator kennen, kennen sie sich vielleicht sogar gegenseitig.
Da gibt es verschiedene Möglichkeiten, wie man es implementieren kann.
Okay, also dieses Interface gibt es schon,
das ist ja schon von Java vorgegeben, das auch,
müssen wir nicht selbst implementieren.
Die Liste ist auch schon da. Wir müssen jetzt
diese Iteratorklasse schreiben. Okay. Tja, wo schreiben wir
die denn mal hin
Ja. So, diese Iteratorklasse braucht ja irgendwie Zugriff auf
dieses Array und wahrscheinlich auch irgendwie auf die Länge,
damit dieser Iterator weiß, ob er schon fertig ist oder nicht.
Und was man jetzt machen kann, ist einfach die Klasse,
die auf diese beiden Eigenschaften zugreifen muss,
in die Klasse Stringlist reinzubauen.
Ja, ich kann also in einer Klasse eine weitere Klasse bauen.
Warum nicht? Ich zeige es euch einfach. Also,
Klaas, wie wir es nennen,
Stringlist-Iterator wollten wir es nennen,
Literator. Und was sollte sie nochmal implementieren?
Wir schauen uns das nochmal ganz kurz an.
Sie soll ja dieses Interface implementieren, Literator.
Und jetzt muss ich da ja noch so ein Typargument angeben.
Über was für Elemente iteriere ich denn hier?
Sind das Kunden oder irgendwelche anderen Sammlungen oder sowas,
über was iteriere ich hier? Ja. Über Strings,
genau. Deswegen ist es ein Iterator über Strings.
Okay. Gut. Jetzt überlegen wir uns vielleicht als allererstes mal,
Was für einen Zustand braucht denn so ein Stringlist-Literator?
Also auf dieses Ehre und Lames kann ich einfach so zugreifen,
aber das reicht dann nicht.
Ich muss mir irgendwie merken, wo bin ich denn gerade?
Bin ich gerade ganz am Anfang? Bin ich irgendwo in
der Mitte? Bin ich schon irgendwo am Ende?
Also ich muss mir irgendwie so einen Index merken,
wo ich gerade bin. Also in, nehmen wir das
ruhig Index, das ist ja ein schöner Name.
Setzen wir es mal auf Null am Anfang, ja?
Gut. Okay, und jetzt können wir die Clips mal bitten,
dass wir uns die drei Methoden hier mal vorgibt.
Also ich muss erst mal importieren, das vergesse ich auch immer.
Sonst weiß ich ja gar nicht, was es ist.
Und jetzt kann er mir diese drei Methoden mal ausimplementieren.
Has next, next only move, natürlich nur mit sinnlosen
Rümpfen.
Wie kann ich denn jetzt bestimmen, ob noch Elemente da sind?
Also in unserem konkreten Beispiel hatten wir ja fünf Elemente.
Und am Anfang, nehmen wir mal an,
wir sind ganz am Anfang gerufen, die Methode zum
ersten Mal auf und hier steht jetzt eine Null drin.
Sind da noch Elemente da? Bei eins auch, bei
zwei auch. Drei auch, vier auch. Jetzt kommt
irgendwo dieser Umbau bei fünf. Habe ich noch ein Element,
wenn ich bei Index 5 bin, wenn ich fünf Elemente habe?
Nee, da schüttelt jemand den Kopf. Das heißt also,
nur wenn der Index kleiner ist als die Länge,
das ist im Prinzip dieselbe Bedingung,
gehen wir noch mal ganz kurz in Main rein.
Das ist im Prinzip genau dieselbe Bedingung, die hier steht.
Nur dass dieses Lenk, das wird da jetzt
quasi direkt drauf zugreifen und nicht über die Methode.
Und dass das I jetzt eben nicht hier so ein Schleifenzähler
ist, sondern der Zustand des Iterators
Okay. Ja, dann sage ich doch einfach alles klar.
Gib doch mal zurück, ob der Index, kleiner ist als die Länge.
Dann ist noch was da. Gut. Schauen wir nochmal
ganz kurz in den Vertrag dieser Methode. Die Frage ist ja auch,
ob der jetzt hier irgendwie weitergeschaltet werden muss oder so.
Returns the next element in the iteration. Hat es kommt,
ja, steht hier vielleicht nicht so 100 Prozent eindeutig,
aber nehmen wir an,
wir rufen die Methode zum allerersten Mal auf,
dann muss sich das Element zurückliefern,
was eben an dem Index 0 steht
Aber sozusagen, bevor ich aus der Methode zurückspringe,
muss ich den Index noch um einen erhöhen,
sonst würde ich ja jedes Mal mir dasselbe Element angucken.
Das können wir vielleicht gleich mal aus Spaß machen, dass ich das vergesse.
Also ich gebe mal ganz kurz das Element zurück,
an der Stelle Index und erhöhe den jetzt mal nicht.
Und was machen wir mit dem Remove? Was war da erlaubt?
Weil ich darf eine Unsupported Operation Acception schreiben, wenn ich zu faul bin,
ist zu implementieren und ja, machen wir das doch mal.
So, ne? Okay. Okay,
ich habe also diesen Iterator jetzt geschrieben, einen Iterator,
der am Anfang beim Index 0 ist,
ja, eine Auskunft darüber gehen kann,
ob er noch nicht fertig ist,
ob noch weitere Elemente kommen
Und der eben dann auch das Element zurückgeben kann, wo er gerade ist.
Ja, und entfernen hatte ich jetzt keine Lust zu.
Jetzt fehlt auch aber noch irgendwas, oder?
Schauen wir uns das Diagramm noch mal ganz kurz an.
Dieses Stringliss implementiert noch nicht dieses Interface.
Das fehlt noch. Machen wir das mal als nächstes.
Implements, Iterible of String. So, muss ich das
wieder importieren? Nö, das kennt er komischerweise schon.
Ad unimplemented Methods. So, jetzt sind die wahrscheinlich ganz unten.
Da ist sie, ich hole die mal hoch,
dass das nicht so weit weg ist
Wo wollen wir es hintun? Ich stoße mal direkt hier, ja?
Dann sieht man es vielleicht ganz schön. Okay. Okay,
also die Klasse verspricht, ich bin iterierbar, iterierbar sein heißt,
ich kann einen Iterator zurückliefern und hier ist die Klassendefinition des Iterators.
Was muss ich jetzt hier drin noch machen?
Denkt doch doch mal Flatzehn oder zwanzig Sekunden drüber nach,
das sind jetzt ja eigentlich Java-Basics, oder?
Ich habe eine Klasse, ich will ein Exemplar auf uns
zurückliefern, ja? Genau. It churn new Stringlist-Iterator.
Jo. Okay. Ja, ich glaube,
er beschwert sich nicht mehr
Dann mache ich jetzt einmal, Moment, wo ist man?
Main, hieß man Main. Ja, okay,
verdammt, jetzt ist es ja schon verraten.
Ihr seht, der Fehler ist jetzt weg. Also ich wollte
euch einmal zeigen, wie man diese Methoden direkt benutzt.
Und nicht so indirekt und hübsch über die Foyed-Schleife.
Hallo? Ja. Ich kann diese Iterator-Methodia benutzen. Ich
kann also diesen Wissenschaftlern sagen, gib mir doch meinen Iterator.
So, das tue ich mir in eine lokale Variable.
Ja, ich nenne es mal It,
da muss ich nicht immer so viel tippen.
Jetzt habe ich mir also einen Iterator geholt,
einen Iterator, der ganz am Anfang der Liste steht
Und kann jetzt sagen, hey,
solange du noch ein nächstes Element hast, ups,
das will ich in der eigenen Zeile haben.
Ja, hol dir doch mal diesen Wissenschaftler. Das ist dann
quasi it.next, tu das mal in eine lokale Variable.
Hallo? Da sind wir, nennen wir das mal Scientist.
Und dann gibt es mal auf die Konsole aus.
So, ja? Also, so musste man,
bevor es Java 5 gab, also vor elf Jahren,
So musste man Übersammlung iterieren, wenn man das recht allgemein machen wollte.
Wenn man sagen wollte, ich kann über Sets iterieren und
ich kann über Listen iterieren.
Und bei Sets gibt es ja keinen Index.
Also kann ich nicht so eine Indexschleife nehmen, wie ich hier oben.
Ich weiß einfach nur, ich habe eine Sammlung,
ich kann mit dem Iterator darüber iterieren.
Und das hat fast niemand gemacht. Ja, in dieser
Form. Warum nicht? Warum hat das fast niemand gemacht?
Ja, Vater, ja. Ich habe Vater,
den Rauben, den Rauben,
Feuer bei Glauben
Feier. Es ist umständlich, ne? Es ist irgendwie auch nicht wirklich hübscher als das Ding hier oben für ein ganz kleines Bissen,
aber ich muss ja auch schon wieder,
dieses IT muss ich jetzt irgendwie dreimal hinschreiben,
ich muss selber wieder über irgendwelche Wild-Bedingungen nachdenken und so,
dann hat man später noch das Problem,
oh, dieses IT gibt es jetzt ja immer noch,
da kann ich ja noch irgendeinen Unsinn damit machen, ja,
obwohl der Iterator ja eigentlich jetzt seinen Sinn und Zweck schon erfüllt hat.
Also das macht einfach keinen Spaß, das so zu schreiben.
Deswegen haben die meisten das weiter und so. Ich sehe auch,
das sind ja hier eigentlich nur zwei relevante zwei Code, ne?
Einmal der Kopf der Schleife und hier im Rumpf der Schleife
ist nur auch eins so ein Ding,
wobei das könnte ich natürlich auch eine eigene lokale Variable tun.
Und hier ist es irgendwie ein bisschen mehr und das sieht einfach blöd aus.
Also hat man sich irgendwann überlegt, Java-Sprachdesigner. Das ist im Prinzip,
ja, man kann eigentlich sagen, das ist,
ja, die Verwendung des Iteratormusters, aber es ist hässlich.
Können wir das nicht schöner in die Sprache einbauen?
Und das ist dann im Prinzip genau das, was sie gemacht haben.
Ja. So. Vielleicht tue ich das mal in zwei eigene Methoden,
dann ist es vielleicht noch klarer. Also ich sage,
ich nehme nochmal eine Methode, die nenne ich mal Oldschool.
Da tue ich mal die alte Variante rein. Das ist
ja quasi die hier. Wobei, das ist jetzt blöd,
weil ich auf die Scientists ja gar keinen Zugriff habe.
Da muss ich dir immer ein Parameter übergeben,
das ist ja kein Problem.
Also das hieß also eine Stringlist namens Scientists
, okay
So, dann mache ich nochmal eine New School,
gibt es das Wort oder nennt man das anders?
Weiß ich ehrlich gesagt nicht. Da tue ich dann mal
die neue Variante rein. So,
und ich möchte schon mal den ganzen anderen Kram,
das ist ja nicht mehr spannend, oder?
Weg mit dem alten Kram. Und dann rufe ich die
einfach mal auf, also Oldschool, Scientists und New School Scientists.
Ah, was habe ich falsch gemacht?
Ach, sie sind nicht Static
Ups. Okay. Und ab und zu mache ich ja gerne
so spannende Dinge mit euch. Ich wollte euch einmal ganz kurz zeigen,
wenn ich meinen, ah nee, das ist in meinem Git-Verzeichnis.
Da muss ich nochmal rein, ja. Okay. Ja
, genau. Also in dieser krassen Stringlist kann ich jetzt mal schauen,
wie unterscheidet sich eigentlich der generierte Code,
der sozusagen aus diesem Oldschool-Quelltext generiert wird,
von dem Code oder dem JavaBartcode,
der von diesem Neuen generiert wird.
Keine Angst, ihr müsst nicht JavaBitecode lesen können,
aber wir können ja zumindest so einen Diff
sozusagen im Kopf mal ablaufen lassen
Okay. Wo ist dieses Oldschool? New School? Sie
sind länger, als ich gehofft hatte, glaube ich.
Oh, ich habe die falsche Klasse genommen.
Main wollte ich eigentlich machen. Ich bin auch einer.
Deswegen waren das so komplizierte Methoden. So, nochmal.
Wo sind Oldschool und New School? Hier sind sie,
ne? Also, wir gucken uns das nochmal auf einer
ganz abstrakten Ebene an. Also, old school.
Wir gucken uns nochmal die Methoden auf auf vielleicht an.
Also, hier gibt es so tolle Kommentare. Okay,
also erstmal wird sich ein Iterator besorgt. Klar,
ich habe ja gesagt, gib mir ein Iterator,
das habe ich ja ganz explizit gesagt.
Was passiert als nächstes
Next, dann rufe ich das Next auf.
Okay. Wo wird denn hier das Hesnext aufgerufen?
Habe ich da irgendwie Unsinn programmiert? Dieses Hasnext,
das muss ich doch hier eigentlich auch finden, oder?
Bin ich, bin ich gerade blind? Das ist komischerweise
erst hier. Ach, hier ist ein Goto. Ah,
Goto-Statement-Consutered haben vorher. Also die Java wird schon maschinen,
wenn sie hier ist, springt sie erstmal nach dir unten.
Ja, das hat mich eben verwirrt,
weil ich bin keine Gotos mehr gewöhnt, alles klar.
Also hier unten prüfen wir mit dem Hasnext, ob es noch was gibt.
Und falls ja, springen wir in Zeile 8,
macht das nicht Spaß, durch die Gegend zu springen.
Dann wird dieses Next aufgerufen und dann das System outprint on.
Also ihr seht, natürlich sind ja die Methodenaufrufe im Bycode,
die wir selber von Hand hin geschrieben haben.
Und jetzt schauen wir uns mal das New School an.
Ob das da irgendwie anders ist. Aha. Ja,
hier wird der Iterator erzeugt. Hier ist das heißen Ext und hier
ist das Next. Ja, und ihr seht das,
das geht hier von 0 bis 34, genau wie hier oben.
Es ist exakt dasselbe. Ja, also keine Angst,
ihr müsst nicht alles verstehen, was hier steht,
aber es ist wirklich exakt dasselbe.
Das heißt also, es macht keinen Unterschied,
ob ihr jetzt so hässlich hinschreibt oder so, hübsch.
Ja, ihr müsst also keine Angst haben, dass das hübsche
irgendwie langsamer ist oder irgendwas anderes im Hintergrund macht oder so.
Es macht hundertprozentig exakt dasselbe. Das heißt also,
es gibt ja so Bytecode oder so
Programme, die nehmen den Bycode und machen das zurück in Quelltext.
Es kann gut sein, wenn ihr sowas schreibt und das
dann zurück umwandelt, dass dann irgendwie sowas dabei rauskommt.
Es gibt keinen Unterschied zwischen diesen beiden Varianten. Das finde ich irgendwie
ganz nett. Okay, gut. Das heißt also,
man hat sich, die Java-Sprachdesigner haben sich recht früh dafür entschieden,
dieses Entwurfsmuster-Iterator ist irgendwie so wichtig, dass wir dafür speziellen Sprachsupport einbauen.
Wir haben dieses Interface und dieses Interface beides in der Standardbibliothek
drin, das war schon immer so.
Und dann haben sie irgendwann so nach zehn Jahren gemerkt,
die Benutzung ist noch ein bisschen hässlich,
dann bauen wir nochmal speziellen Sprachsupport ein,
wirklich in den Kern der Sprache,
damit man dieses For-Each quasi hinschreiben kann
Wir sind auch nicht ganz fertig. Was ist denn hier mit diesen Dependency-Filen?
Also schauen wir noch mal ganz kurz. Kann mir jemand sagen,
welche Abhängigkeiten ist zwischen Stringlist und Stringlist-Iterator gibt,
sind die völlig voneinander entkoppelt oder kennt der eine den anderen
oder andersrum oder kennen sie sich beide gegenseitig?
Wie sind da die Abhängigkeiten? Ja,
die Rücken des Versuchs der Bücher, die verraten,
nur alle, die es wirklich gelöst haben.
Vater,
Vater, Vater
Also Stringless kennt ihr im Iterator schon mal richtig.
Das sieht man ja ganz eindeutig hier.
Ich bin hier, also das ist die Klasse Stringless.
Ich bin hier in einer ganz normalen Methode der Klasse Stringlist
und in der Methode der Klasse Stringless greife ich auf diesen Iterator zu.
Also brauche ich diesen Iterator, sonst wäre die Klasse gar nicht übersetzbar.
Das heißt, es gibt auf jeden Fall eine Abhängigkeit in diese Richtung.
Die Frage ist jetzt, gibt es auch eine in die Gegenrichtung?
Also greift der Stringless-Iterator irgendwo auf,
ja ist er davon abhängig, von der Klasse Stringless,
greift er da irgendwo auf etwas zu von der Klasse Stringless
Ja, also wir greifen auf diese Unterstrich-Unterstrich-Lenk zu,
was ja hier aus der Kasse String,
das kommt nur noch auf dieses Unterstrich-Array.
Das heißt, wir haben hier eine zyklische Abhängigkeit.
Das ist aber nicht so wahnsinnig schlimm,
weil der Herr hatte ja schon gesagt,
diese Klasse Stringless-Iterator ist ja eigentlich ein Implementationsurteil der Klasse Stringless.
Ich könnte die sogar private machen. Dann belästige ich meine Klienten
nicht an der Schnittstelle, dass es noch diese Klasse gibt.
Das müssen Klienten also gar nicht wissen. Man kann also sagen,
die sind so eng miteinander konzeptionell,
sind sie auch schon so nah beieinander,
dass es nicht schlimm ist,
dass es diese gegenseitige Abhängigkeit gibt.
Ja, sehr schön. Gibt es noch Fragen zum Iteratorentwurfsmuster?
Was ist denn mal ein schöner, ja, eigentlich hier,
das ist ja schon eine gute Stelle, ne?
Also hier, hier sieht man es nochmal schön zusammengefasst.
Eine Stringlist ist iterierbar. Was bedeutet es, dass sie
iterierbar ist? Es bedeutet, dass sie diese Iterator-Methode anbietet.
Was ist das für ein Iterator? Eine Klasse,
die wir selber geschrieben haben, diese. Und sie ist
deswegen ein Iterator, weil sie diese Iterator-Interface implementiert.
Und wie ist dieser Iterator aufgebaut? Er weiß, wo
er ist. Er kann die Frage beantworten, ob noch Relemente kommen.
Und er kann mir das Element zurückgeben, wo er gerade ist.
Ah. Und wir hatten ja noch was vergessen.
Wir haben es gar nicht getestet. Fast hätte ich
euch mit diesem Fehler nach Hause geschickt
Rufe ich diese Methode irgendwo auf.
Ja, genau. Dann starte ich das doch mal.
Ja, seht ihr was? Newton ist so wichtig,
dass er als einziger Wissenschaftler unendlich oft auf die Konsole geschrieben wird.
Tja. Das ist ja blöd, ne?
Woran liegt das denn? Ja. Ja,
irgendwie muss man den Index weiterschalten, ne?
An welcher Stelle wäre das denn sinnvoll? Davor, danach?
Ja. Danach bedingt, weil wir von uns ja immer,
wenn ich an einen Pult bin, Und wir dann ja gehen.
Genau, also wir können es nicht vorhören.
Wir müssen danach, aber das Blöde ist ja,
nach dem Return wird ja nichts mehr ausgeführt.
Also wenn ich jetzt einfach nur schreibe, plus plus Index,
dann beschwert sich wahrscheinlich ihr Clips.
Ja. Hm, tja, was machen wir denn jetzt?
Oh, zwei Ideen, du hattest heute noch nichts.
Voll oder wenig. Stimmt, das ist wahrscheinlich die einfachste Möglichkeit.
Ich schreibe es einfach davor und sagt dann hier Index minus eins.
Ja, das ist wahrscheinlich pragmatisch einfachste Möglichkeit.
Du hast eine andere Idee? Ich muss kurz schreiben,
weil du bist zuerst. Ah. Das ist tatsächlich eine
der wenigen Stellen,
wo dieses Index plus plus ganz hübsch ist
Das könnte man tatsächlich machen. Vielleicht ist das sogar hier tatsächlich
die hübscheste Variante. Ich lasse euch damit mal drüber nachdenken.
Okay. Oh, was man auch machen kann,
da fällt mir gerade ein, das ist vielleicht ganz witzig,
wir könnten das ja auch zurückgeben.
Und dann erhöhen. Funktioniert das? Man muss einmal ausprobieren
. Also bitte schreibt so einen Code niemals selber.
Ich will einfach nur mal wissen, ob das von der Java-Semantik das Richtige macht.
Ich gehe jetzt mal in meinen Main zurück und rufe jetzt
vielleicht auch mal nur das New School auf,
das macht ja hier keinen Unterschied.
Ich will nur nicht,
dass es da zweimal steht
Und mal gucken, was jetzt passiert. Ja, das sind
die fünf, ne? Ja, aber, mein Gott,
also bitte schreibt sowas nicht, das versteht ja keiner.
So, also das mit dem Index Plus Plus war doch eigentlich schon ganz nett.
Also. Stimmt, das haben wir gar nicht gemacht.
Also testen nach dem Motto von Handtesten, wir fühlen es
einfach aus und gucken, ob immer noch dasselbe rauskommt.
Ja, sehr gut. Okay, ja, genau,
ich hatte, ich hatte ja gerade schon zusammengefasst und
dann bin ich auf den Fehler geschossen.
Gibt es noch Fragen zum Iteratorentwurfsmustern
Ja. Jetzt wollen wir uns um den Tag Paris.
Du meinst Frau Eaches langsamer wegen der Abfrage?
Du meinst dieses Hasnacks quasi? Na gut,
wir haben diese Abfrage in dem Sinne ja auch,
ach, die Schlafe habe ich schon gelöscht, ne?
Mist. Also du hast so ein kleiner Vergleich ja
auch in der normalen Schleife. Oder meinst du,
weil das jetzt in einer eigenen Methode drinsteht?
Ich bin mir nicht sicher, wie gut die Hotspot-Virtual-Maschine das inlinen kann.
Schreib mir einfach mal einen Test und sag mir,
was dabei rausgekommen ist. Ich weiß es nicht.
Aber ich glaube, in der Praxis ist das
noch nie
ein Problem gewesen
Okay, oh, irgendwelche Imports, die ich nicht brauche, weg damit.
Gut. Das war also der Iterator. Den speichert mir auch
mal ganz kurz. Jo, dann haben wir den Iterator.
Okay. Ja, zum OML-Klassenlehrer haben wir noch Fragen.
Also wenn ihr mal in den Gamma reinguckt,
also dieses Buch von Mitte der 90er,
da heißen dann die Methoden ein bisschen anders oder vielleicht gibt es auch vier Methoden statt drei,
vielleicht kann man nicht nur vorgehen, sondern auch zurück.
Ich habe jetzt eben diese Variante genommen, die schon in
Java eingebaut ist, um euch nicht unnötig zu verwirren.
Also so ein Entwurfsmuster ist nie 100 Prozent in Stein gemeißelt,
sondern es gibt da immer so ein paar Variationen,
wie man die Methoden anders nennt
Jetzt ist mir das ja immer schon vorbei. Und zwar
spricht das, dass er auch durch einen zu pökerzieren wird.
Das hat einfach das Kollege, das Pöker.
Korrekt. Warum können wir auch das Array zugreifen?
Das ist so eine interessante Eigenschaft von Java.
Ich bin da jetzt gar nicht so explizit darauf eingegangen,
weil das ein recht umfangreiches Thema ist. Man kann also,
wenn ich in einer Klasse eine andere Klasse schachtel,
dann kann ich in der, ich will jetzt kein falsches Wort sagen,
heißt das innere Klasse?
Ich glaube ja. Dann kann ich in der
inneren Klasse auf Exemplarvariablen der äußeren Klasse zugreifen.
Das geht einfach. Ist ganz nett. Ja, genau
Okay. Nur weil sonst müsste ich ja irgendwie diese Variablen
erstmal hier in irgendeinem Konstruktor reinstecken und sie in mir in meinen eigenen Feldern merken,
das wäre irgendwie einfach nervig, ja.
Entschuldigung, das ist jetzt aber ein Partner,
das was dir jetzt innerhalb von 5 aus dem Brief ist,
das ist gerade, das ist überfordert.
Nee, es ist absolut so, dass ich nur innerhalb
der Klasse Stringlist Zugriff darauf habe.
Also du kannst nicht von außen sagen, stringlist.stringlist-Eteratung würde sagen,
sorry, da darfst du nicht darauf zugreifen, das ist privat.
Ja. Gut. Ja, das war also das,
dann schließe ich mal wieder alles gut.
Jetzt hatte ich so ein ganz kleines Dilemma
Wir kommen zum nächsten Thema Beobachtermuster. Und zwar, ja,
also ich will natürlich immer nah an der Übung sein.
In der Übung gibt es eine Aufgabe zum Beobachtermuster.
Und da verwendet ihr natürlich auch schon Googies und ich wollte
es jetzt hier genauso machen.
Ich habe jetzt also hier mal was gebaut. Googies,
da haben wir das. Das ist also mein eigener Excel-Clone.
Ich weiß nicht, ob jemand den Wortwitz verstanden hat.
Man kann aber noch nicht so wahnsinnig viel damit machen.
Ich kann ja so durch die Gegend gehen, toll.
Und man hat ja unten so eine Anzeige,
kann man
das lesen
Oh Gott, das ist ja viel zu weit links.
Ich schiebe es wieder nach rechts. Man hat hier so
eine Anzeige, in welcher Zelle ich gerade,
wenn ihr seht, wunderbar, wird völlig ignoriert.
Da steht einfach nur eine Konstante drin. Okay, darum
kümmern wir uns noch. Und was vielleicht auch blöd ist,
wenn ich jetzt hier irgendwas hinschreibe, das kann keiner lesen, oder?
Auch doch. Okay. Aber für die Leute,
die vielleicht das nicht so gut lesen können, habe ich noch was eingebaut.
Und zwar, die Zelle, wo ich gerade bin,
die wird hier nochmal so vergrößert dargestellt.
Ja, das ist doch vielleicht ganz nett.
Also wenn ich jetzt hier so durch die Gegend gehe,
dann seht ihr immer schön groß, was da wirklich steht.
Jo. Okay
Das sind jetzt drei unabhängige Klassen voneinander. Ich habe also
eine Klasse, die Sicherung und diese Vergrößerung kümmert.
Irgendwie so eine kleine grafische Oberflächenkomponente.
Eine, die sich um diese eigentliche Tabelle quasi kümmert.
Und eine, die sich hier unten um diese Anzeige kümmert,
wo bin ich denn gerade?
Ja, und es gibt schon irgendwie offenbar so eine Verdrahtung
irgendwie zwischen diesen beiden Komponenten. Vielleicht ist das gar nicht
so gut. Und diese Verdrahtung gibt es noch nicht.
Okay. Und so ein ähnliches Szenario bis in den Übungen,
ja, ihr habt irgendwie dieses... Ich habe das doch dabei,
ich muss das gar nicht so abstrakt machen.
War das nicht
dieses Projekt
Ja, genau. Das ist ja das,
was ihr in den Übungen macht,
wo man irgendwie einmal hier so ein Werkzeug hat,
irgendwie das Datum Auswählwerkzeug, dann hat man ja irgendwie das
Vorstellungsaufelisterwerkzeug oder so und dann hat man hier das Platzverkaufswerkzeug oder so heißt das,
glaube ich.
Wo es eben auch Zusammenhänge zwischengeben soll. Also immer,
wenn ich hier das Datum auswähle,
soll zum Beispiel sich das hier unten anpassen und immer,
wenn ich hier was anderes auswähle, soll sich das da rechts anpassen.
Und die Frage ist, wie verdrahte ich das? Ja,
will ich, dass diese Werkzeuge sich irgendwie gegenseitig kennen?
Also soll dieses Datum auswählwerkzeug wissen,
dass es dieses Werkzeug gibt und dann direkt Methoden darauf aufrufen?
Ist ja vielleicht irgendwie nicht
so schön
Vielleicht will man dieses Datum auswählen, Werkzeuge auch in anderen Kontexten
mal einsetzen, die gar nichts mit Vorstellungen zu tun haben.
Okay, das ist also die Aufgabe in den Übungen.
Und so ähnlich ist es hier jetzt eigentlich auch.
Nur, dass das System deutlich einfacher ist. Ich habe jetzt
also irgendwie nicht 100 Klassen oder so, sondern nur fünf.
Okay. Und auch diese ganze Unterteilung mit Werkzeugen und Service und so,
das habe ich jetzt mal hier alles rausgenommen,
um mich nur auf dieses Beobachtermuster konzentrieren zu können.
Okay. Ja, und schauen uns die Klassen noch einmal
ganz kurz an, oder? Also Sheet,
das ist quasi das Werkzeug in der Mitte. So,
jetzt kommen hier, wie gesagt, so ein paar Sachen,
die Guido erst nächste Woche einführen wird.
Also wie werden überhaupt grafische Oberflächen realisiert?
Da müssen wir jetzt mal einfach so
ein bisschen rüberfliegen
Und wir schauen mal, wo jetzt hier die interessanten Dinge passieren.
Okay, also das sagt einfach nur, das ist so
eine Tabellenform sein soll. Okay, das ist alles Google-Kram,
das ist die Größe, das ist alles nicht so spannend.
Ja, wo ist denn jetzt hier die Logik,
dass dich die Magney Freibestatt sagt?
Das ist hier. Dann mache ich mal To-do rein.
Also To-do, Sheet kennt Magney Fire. Das finde ich
irgendwie nicht so gut. Wie lange würde ich den Magney
Fire irgendwann mal ausbauen oder noch einen zweiten Magney Fire,
der das auch in Blau zusätzlich darstellt oder kursiv oder was weiß ich.
Also ich will nicht irgendwie fest verdrahten hier drin,
dass es diesen Magney Fire gibt,
das finde ich irgendwie blöd,
will ich nicht.
Ja, und das reicht eigentlich schon fast als Motivation,
um jetzt über das Entwurfsmusterbeobachter zu reden, was Guido ja letzte Woche schon gemacht hat.
Also warum kann ich nicht einfach sagen, jedes Mal,
wenn ich hier irgendwo hinklicke,
könnte doch dieses Sheet sagen, hey,
wer auch immer sich dafür interessiert, dass hier gerade,
dass ich hier gerade in einer anderen Zelle gelandet bin,
sei das jetzt durch Mausklick oder durch Tastatur, das ist ja egal.
Ich gebe euch mal Bescheid, dass sich was getan hat.
Ja, alle Leute, die das interessiert, denen kann
ich Bescheid sagen. Und was die dann damit machen,
ob die irgendwas groß darstellen oder ob die irgendwelche Positionsangaben irgendwo darstellen,
das ist mir völlig egal.
Ich sage ihnen einfach nur, es ist irgendwas Spannendes passiert.
Und vielleicht fangen wir hier auch mal wieder an mit dem OML-Diagramm.
Das ist immer so eine tolle Übung, die man in
mündlichen Prüfungen machen muss. Sehen habe ich das hinbekommen.
Also, Guido hatte das ja schon letzte Woche vorgestellt.
Ich versuche das jetzt mal nachzubauen. Also, es gibt
einmal diese Interface-Beobachter. Das sind also diejenigen Leute,
die sich dafür interessieren, dass sich etwas ändert.
Das ist also einmal dieser Magnify und unten diese Positionsangabe.
Die werden das später mal sagen. Okay, wie nennt
man die Methode, die nennt man häufig sowas wie Reagiere auf Änderung.
Das ist schon ein Name, den wir immer ganz gerne im Übungsbetrieb nehmen.
Ihr könnt das aber auch Update nennen oder Change oder was auch immer.
Ich finde das aber eigentlich einen ganz netten Methodennamen.
Okay, das ist die Zutat Nummer eins
Dann gibt es eine abstrakte Klasse. Wo sage ich das
jetzt? Kann ich irgendwo sagen, dass sie abstrakt ist?
Nee, ich muss es wieder von anschreiben.
Die nennen wir Beobachtbar. Und die hat jetzt intern eine
Sammlung, die nennen wir mal alle Beobachter.
Vom Typ ist ja irgendeine Sammlung halt Beobachter. Ich kenne
meine Beobachter. Sonst kann ich denen ja nicht Bescheid sagen.
Ich muss die irgendwie kennen. Okay, hat jemand eine Idee,
warum ich das alle Beobachter nenne und nicht einfach nur beobachte?
Ist das schon die Antwort auf die Frage,
dass ich schon vorher gemeldet,
Aber ich weiß nicht, ob die jetzt noch auf der Welt war.
Mein Gott, mein Gott, bitte, dass wir die
Böcke heilig sind. Du willst in Magneyfire's Static machen.
Da sehe ich noch nicht so wirklich den Sinn hinter.
Und wir würden das dann ja genauso hart verdrahten, dass ich sage,
rufe jetzt mal die statische Methode von diesem Magneyfire auf.
In die Richtung will ich jetzt nicht gehen. Ich will tatsächlich
dieses Muster einsetzen. Und dann hat immer eine Idee,
warum ich das gerne alle Beobachter, Stadtbeobachter nenne.
Das hat damit zu tun, dass ich generell lieber
auf Englisch programmiere als auf Deutsch.
Vielleicht ist das ja ein Hinweis. Ja,
das Blöde an Beobachter ist, falls sich jetzt keiner meldet,
3-2-1,
Single und Plural ist gleich. Das heißt, ich sehe
am Namen nicht, ist das jetzt einer oder mehrere,
das stört mich. Also ich will,
dass es völlig klar ist, wenn man das nicht,
das ist da überhaupt keine Verständnisschwierigkeiten geben kann, dass es mehrere sind.
Ja. Okay. Und es gibt Methoden. Wie war
das nochmal? Wir erinnern uns zurück an letzte Woche.
Also es gibt erstmal diese Collection, aber die ist ja erstmal leer.
Eine leere Collection ist ja wahrscheinlich nicht für immer sinnvoll.
Ich brauche irgendeine Methode, um einen Beobachter da reinzufügen.
Das heißt meistens Fügebeobachter hinzu. Fügebeobachter hinzu. Und dann
übergibt man den natürlich. Beobachter, Doppelpunktbeobachter. Also stört euch bitte nicht an dieser Synthese,
das ist jetzt keine Java-Synthex, sondern das ist diese andere,
ich glaube Allgäu hatte das mal eingeführt,
also ist der Variablenname dann der Typ und dann,
Das ist nicht der Typ, das ist der Doppelpunkt.
Und dann der Typ. Man will diese OML-Diagamme eben nicht
auf eine bestimmte Programmiersprache münzen. Okay, das ist also das.
Erinnert sich jemand, dass wir noch eine Methode brauchen?
Also ich habe diese leere Sammlung,
ich kann jetzt was in die Sammlung reintun,
aber wir brauchen ja sicherlich auch eine Methode,
die irgendwas macht mit der Sammlung.
Weißt das noch jemand, was eine beobachtbare Klasse mit
seinen Beobachtern so macht ab und zu?
Informiere Beänderung, genau. Das ist dieses Update,
hey Leute, es ist was passiert.
Informiere über Änderungen. Ist das jetzt singular oder plurer?
Ich lasse es mal singular
Also die sind beide Void, ich schreibe das Wort jetzt nicht dahinter.
Das ist jetzt, mir reicht das so. Okay.
Wichtig ist eben, dass da keine Parameter reingesteckt werden. Ja,
und dann gibt es manchmal auch noch dieses entferne Beobachter,
aber das wird sowieso nie aufgerufen, deswegen implementiere ich das gar nicht erst.
Okay. Das ist also das. Jetzt überlegen wir uns wieder
die Abhängigkeiten. In welche Richtung geht jetzt die Abhängigkeit?
Kennt Beobachter, beobachtbar oder kein beobachtbarer Beobachter oder kennen sie
sich gegenseitig oder kennen sie sich gar nicht?
Die vier Möglichkeiten gibt es ja. Ja,
der Beobachter kennt die Beobachter
Du wurdest also in diese Richtung den Fall machen.
Wo siehst du denn hier in dem Interface diese Abhängigkeit?
Dann müsst ihr ja hier irgendwo stehen, beobachtbar.
Steht hier nirgends, oder? Gibt es denn den Fall
andersrum? Also steht hier irgendwo in dieser Klasse unten,
steht hier irgendwo Beobachter. Ja, zweite Chance?
Ja, ne? Hier zum Beispiel, ne?
Und hier auch. Sehr gut. Das heißt,
ich mache ihn hier zurückwärts, gut.
Aber er ist nun in eine Richtung,
das ist ein ganz zentraler Punkt.
So, und jetzt kommen eben zwei konkrete Unterklassen und wir
überlegen jetzt uns für unseren Fall, welche das sind.
Also, beobachtbare, welche von diesen drei Klassen es beobachtbare.
Also ist das irgendwie interessant, wenn hier was passiert?
Soll dann ein Newsletter durch die Gegend geschickt werden oder wenn
hier was passiert oder hier? Also A, B oder C
, welcher Fall ist es? Ja? Richtig,
die Tabelle ist beobachtbar, weil da passieren die interessanten Dinge.
Gut, das heißt, machen wir mal die Klasse hin,
die heißt, glaube ich, Sheet.
Und die erbt jetzt davon?
Okay. Und wer ist jetzt der Beobachter im aktuellen Systemzustand?
Oder wer sollte es sein, wenn wir das gleich
so umbauen, dass der Beobachter benutzt wird?
A, B oder C. Ja. A. Richtig,
also wenn wir heute fertig werden,
dann ist es A und C und jetzt im jetzigen Zustand,
also wenn wir das jetzt nur so,
nur A. Und wie hieß das, Magnefire hieß es,
glaube ich.
Okay. Das heißt,
diese Magnefire-Klasse tue ich jetzt mal hier hin
So, Macney fire. So. Und welche Beziehungen? Ah,
das ist interessant, das ist jetzt doch ein bisschen anders,
als ich es in der Übung gemacht habe.
Ich glaube, wir müssen noch mal ganz kurz in
den Quelltext reingehen, dass wir uns hier nicht überschlagen.
Also das kann man so machen, wie ich es gerade gezeichnet habe,
aber ich habe es tatsächlich in meiner Lösung ein bisschen anders gemacht.
Wir haben uns ja noch gar nicht alle Klassen angeguckt.
Wir haben uns bis jetzt ja nur Sheet angeguckt,
ja, und bei Sheet festgestellt,
dass da momentan hart auf diesen Macney fire verwiesen wird.
Schauen wir uns doch vielleicht mal diese Klasse an.
Diese Klasse vereint sozusagen die anderen drei Klassen, wenn man
so will. Ja, oder fasst sie irgendwie zusammen.
Und so ähnlich ist das ja auch in dem Projekt,
was ihr habt, habe ich das ja noch irgendwo laufen?
Nee, habe ich nicht. Ich muss es noch einmal starten.
Es tut mir leid, dass ich hier so hin und her springe.
Ach, versteht ihr nicht, welches, welche klassisch ausführen will?
Also es gibt hier diese drei Werkzeuge-Datum-Auswähler-Vorstellungsauflister und Platzverkauf.
Aber es gibt eben noch ein Werkzeug und das ist quasi,
wenn man so wie dieses gesamte Fenster,
also das,
was alles zusammenfasst
Und das heißt, glaube ich, ja, wie heißt denn das?
Kassenwerkzeug oder so ähnlich heißt es, glaube ich, ne?
Kann man vielleicht gleich immer korrigieren. Und die Idee,
wie es in der Übung gemacht werden soll, und ich glaube,
es steht auch so auf dem Aufgabenblatt, ist,
dass diese Werkzeuge, diese Subwerkzeuge nennen wir sie ja auch,
dass die sich nicht irgendwie gegenseitig beobachten, so,
hey, du bist mein Bruder, ich beobachte dich mal,
sondern dass das irgendwie schön strukturiert,
von dem Kontextwerkzeug gemacht wird.
Also von diesem Werkzeug, was alles zusammenfasst. Nach dem Motto,
das Datum aus wie Werkzeug gibt nach oben die Meldung,
es hat sich was getan und dann kann oben reagiert werden und gesagt werden,
hey, du musst dich jetzt ändern oder du musst dich jetzt ändern.
Und das wollte ich hier eigentlich genauso machen.
Das heißt also, diese Klasse sollte eigentlich die Beobachtende sein.
Kann man so machen. Also beide Varianten sind möglich.
Ich will das gerne so machen, damit es schöner an den Übungen dran ist.
So, die soll also der Beobachter sein.
Und gibt es jetzt hier noch irgendwelche Abhängigkeiten? Schauen wir
uns das das nochmal vielleicht ganz kurz an. Ja,
also diese Klasse Excel hat zu allen drei Klassen Abhängigkeiten,
die sollte ich vielleicht auch nochmal ganz kurz klar machen.
Also MacDefire, Sheet on Position, tun wir sie alle
mal hier hin. Ich merke, we fire,
ups.
Was ist denn? So. Und die Klasse kennt die alle
. Nehme ich jetzt Depends on oder ist Egregot of,
weil sie fasst sie ja eigentlich zusammen.
Ich bin bei sowas immer nie sicher,
ich nehme einfach ein bisschen einfachen Depends,
weil da könnt ihr euch dann mit euren irgendjemanden Latern streiten,
was da jetzt der sinnvollere Fall ist.
Okay, machen wir es mal so schön auseinander,
geht das irgendwie, dass an sich nichts überkreuzt.
Boah. Ach, das Sheet gab es ja schon,
jetzt habe ich es jetzt
zweimal hingemacht
So. Und das Spannende am Beobachter muss das jetzt folgendes.
Wir haben auf der abstrakten Ebene eine Abhängigkeit,
die von beobachtbar zu beobachten hergeht.
Ich muss jemanden kennen, um ihm zu sagen,
es hat sich was getan, reagier mal drauf.
Auf der abstrakten Ebene und auf der konkreten Ebene ist der Fall
genau andersrum. Ja. Das ist ja ganz spannend.
Das heißt also sozusagen zur Laufzeit sind es dann letzten Endes,
wenn man das so zusammendampft, gibt es dann wieder diesen Zyklus ab,
aber es gibt eben nicht auf Typ-Ebene.
Also es kann euch beim Design nicht besonders viel auf die Füße fallen.
Okay, haben wir damit jetzt alles,
was wir brauchen, um das umzusetzen?
Ich glaube ja
Also rein konzeptionell. Wir müssen natürlich dieses Interviews und dieses
abstrakte Klasse noch bauen. Dann bauen wir die doch mal
. Wir fangen mal hier mit an. Das ist ja
recht einfach. Interface-Beobachter. Fangen wir damit mal an.
Falsches Projekt. Taugen wir es mal hier hin.
Interface. O, Bach, Ter. So,
das hatte nur eine Operation. Reagiere auf Änderung.
So, das war ja einfach. Dann machen wir jetzt
die abstrakte Klasse.
Die hieß Beobachtbar
So, die hatte intern eine Sammlung von Beobachtern.
Ich hatte sie genannt, alle Beobachter,
ich mache mal Vollbild, dass man ein bisschen Bergplatz hat.
Schreiben wir mal einen Konstruktor. Beobachten. Machst du das
immer schöne Wörter? So, und jetzt können wir uns
prügeln. Welche Sammlung nehmen wir? Also New Collection geht
ja nicht, ne? Das wäre ja zu einfach.
Boah. Das geht nicht, weil dir abstrakt ist.
Welche Collection wollen wir nehmen
Welche gibt es denn? Ja. Ein Set könnte man
nehmen. Warum? Stimmt, die Reihenfolge ist egal und
noch eine Eigenschaft von Z. Keine Duplikate, ne?
Das heißt also, ist euch das schon mal passiert,
dass ihr eine Zeitschrift doppelt bekommen habt,
weil ihr zweimal Abonnent wart?
Das wäre blöd, oder? Also Set ist vielleicht
gar nicht so schlecht. Nehmen wir mal ein Hashset.
Damit sind wir vertraut. Gut. Na? Ja.
Gut, dann in Zufügung von Beobachtern,
Füge,
Beobachter hinzu
Den müssen wir übergeben. Ja, Rückgabetyp fehlt.
Zack. Ja, und dann fügen wir mal hinzu.
Dann tschüss. So, ne? Gut, ist er zufrieden.
Was fehlt noch? Reagiere auf Änderungen. War das nicht so?
Ich schaue nochmal nach, dass ich nichts falsch mache.
Informiere auf Änderungen. Was sage ich denn hier?
Gut, dass ich mal noch informiere über Änderungen.
So. Und ja, was mache ich denn jetzt hier
Da muss man auch nicht so wirklich Gedanken drüber gemacht, oder?
Also ich habe diese Liste oder dieses Set, diese Sammlung.
Möglicherweise sind da schon welche drin, wenn nicht,
wäre jetzt auch nicht so schlimm, aber nehmen wir an,
da sind jetzt schon so ein oder zwei Beobachter drin.
Wie sage ich denn denn jetzt Bescheid? Ja,
du hast schon sofort eine Idee,
vielleicht lassen wir mal kurz alle drüber nachdenken,
dass du die Zahnräder rattern, wie würde ich das jetzt tun?
Allen, die in dieser Liste sind,
Bescheid zu sagen, dass sich was getan hat.
Wir können ja gedanklich nochmal ein Stündchen zurückgehen,
als wir über das Iteratormuster gesprochen haben.
Was haben wir denn da?
Ah, du
Machen. Wir müssen über alle Beobachter reden,
das ist manchmal als erstes. Und jetzt hoffe ich,
dass Eclipse so schlau ist, zu sehen,
hier ist ja nur eine Collection im Scope,
da nehme ich mal die, mal gucken.
Ja, toll, oder? Gut, und jetzt?
Darauf jeweils aufrufen, genau. So, okay,
das war doch nicht ganz einfach, oder?
Gut. Das ist jetzt also die abstrakte Ebene oben.
Schauen wir mal ganz kurz an, wo wir gerade sind.
Wir haben das eben implementiert, das war ja eh extrem einfach.
Es war nur ein Methodenkopf. Dann haben wir jetzt das implementiert.
Sehr schön. Ja, was ist denn jetzt das nächste Sinn?
Ich würde mal sagen, dass wir jetzt hier weitermachen oder so,
dass ich also sage, Das Sheet ist beobachtbar.
Das will ich jetzt als nächstes mal angehen.
Das ist also quasi hier. Ha. Da haben wir
ein Problem. Es gibt ja keine Mehrfachwerbung in Java.
Das ist ja blöd, oder? Also ich kann nicht
schreiben, Extense, J-Table und dann auch beobachtbar.
Beobachtbar. Es geht nicht. Ja. Ich habe
11 Stunden frei
Vater, der Organ. Oh, sie ist noch nicht
abstrakt. Stimmt, das können wir auch noch machen.
Ja. Vielleicht ist es ganz gut, dass sie noch nicht
abstrakt ist. Denn wir brauchen jetzt ja irgendeinen Workaround.
Also ich muss von diesem J-Table erben oder zumindest bin ich
ziemlich fest davon überzeugt, dass ich das muss.
Wenn man nicht erbt, dann benutzt man ja normalerweise Delegation.
Also könnte ich nicht Stadt zu erben, einfach sagen,
ich erzeuge mir jetzt ein Exemplar von dir.
Das ist jetzt leider ein bisschen blöd,
das ist jetzt anders als in den Übungen.
Muss ich mal gucken, wie das da gelöst wurde.
Ich erzeuge mir jetzt einfach mal ein Exemplar. Ich nenne das mal,
mir fällt gerade nichts Besseres an, als das beobachtbar zu werden.
Also das ist jetzt wirklich pädagogisch blöd. Ich hätte jetzt
am liebsten davon geerbt, Komisch, das ist mir gestern
gar nicht aufgefallen, dass es dieses Problem gibt.
Verdammt. Also denkt euch bitte, dass ihr stattdessen davon
geerbt habt. Das müsst ihr nämlich im Übungsbetrieb machen.
Verdammt. Okay, wie mache ich denn jetzt diese Anmeldung?
Also ich muss ja irgendwie sagen, an dieser Stelle,
dass ich, ne Entschuldigung, nee,
ich bin an der falschen Stelle.
Wann muss ich dieses Informiere über Änderungen aufrufen?
Das ist ja jetzt hier die spannende Frage, ne?
Hat jemand einen Vorschlag? Wo muss ich jetzt sagen,
es ist was Interessantes passiert
Ich habe ja vorhin dieses To-Do geschrieben. Das wird ja
wahrscheinlich diese Stelle sein. Also ich kombiniere das mal hier mal kurz aus.
So. Und hier würde ich jetzt normalerweise einfach schaden, informiere über Änderungen.
So, wenn ich davon geerbt hätte, habe ich aber nicht.
Außer muss ich das jetzt per Delegation machen.
Oh, ach, da. Blöd. Okay,
also das habe ich jetzt gemacht. Jetzt muss ich natürlich
noch mal am Klienten die Möglichkeit anbieten,
dass er sich als Beobachter registrieren kann.
Normalerweise wäre das automatisch durch die Vererbung.
Normalerweise würde ich jetzt einfach diese Methode Fügelbeobachter hinzuhaben
Dadurch, dass ich jetzt aber nicht geerbt habe,
muss ich diese Methode nochmal selber schreiben.
Ich bin wirklich unglücklich damit. Ich werde nächste Woche nochmal vielleicht
eine schönere Lösung zeigen, weil gerade fällt sie mir nicht ein.
Gut, sage ich also, Vögel, Beobachter hinzu.
Das ist einfach völlig mechanisch, dass ich jetzt diese Weiterentlatung mache.
Immer wenn man das Problem in Java hat,
ich will von was erben, aber ich erb schon von was anderem,
dann muss man es leider so machen.
Punkt, da haben wir es. Ich lade diese Anfrage
einfach weiter an dieses Beobachtbarobjekt. Okay, sollte hoffentlich funktionieren
Gut. Das haben wir jetzt also auch gemacht.
Ich habe also dafür gesorgt, dass mein Beobachter hinzufügen kann.
Ich habe das informiere über Änderungen an der richtigen Stelle aufgerufen.
Jetzt fehlt noch dieser Teil. Also dieses Excel soll
informiert werden, wenn sich was getan hat.
Also wir müssen dieses Interface implementieren. Das ist zum Glück
ein Interface, der kann nicht schiefgehen.
Das kann ich ja immer machen. Also gehe ich zu
meinem Excel und sage, Implements, beobachte.
Jetzt beschwert er sich natürlich, dass ich diese Reagiere auf
Änderungen nicht mache.
Das machen wir einmal kurz
Und vielleicht machen wir erstmal nur ein System Outprintline,
dass wir überhaupt sehen, dass es ausgeführt wird.
Also ich wurde aufgerufen. Oder es hat sich was getan.
Es hat sich was Interessantes getan. Ja, so. Bock,
na, wieso ist das so hässlich? So. Also in dieser Klasse,
jedes Mal, wenn also was Interessantes passiert,
rufe ich dieses Informiere über Änderung auf, was passiert bei diesem Informiere über Änderungen,
springen wir da noch mal ganz kurz rein.
Da wird ja über alle Beobachter rübergegangen und dann wird dieses
Reagiere auf Änderung aufgerufen. Das Interessante ist jetzt aber,
Wenn ich das nochmal neu starte, ich schließe mal hier die alte Version.
Wenn ich das nochmal neu starte, ach, falsches Projekt.
Wenn ich es neu starte, zum dritten Mal,
und ich schreibe jetzt mal hier was rein, dann passiert überhaupt nichts.
Also es wird hier unten, ich würde jetzt erwarten,
dass hier steht, es hat sich was Interessantes getan.
Passiert aber nicht. Das sind ganz typische Anfängerfehler.
Warum passiert jetzt nichts? Also ich habe doch gesagt,
ich habe doch gesagt, dass Excel ein Beobachter ist.
Warum wird diese Methode jetzt nicht aufgerufen?
Das ist ein, ja. Nur weil,
das gibt es ja auch im Verein beurteilen auf der Liste,
das heißt, weitergehen. Wird der im Hochhaut fahren?
Sehr gut, wir müssen uns registrieren, ne?
Wann ist denn mal eine gute Möglichkeit, dass du,
ich mache es einfach mal am Ende des Konstruktors, ja?
Fällt mir gerade nichts Besseres ein. Also, hey,
Sheet, füge doch mal einen Beobachter hinzu.
Und wer ist jetzt der Beobachter? Ja. This,
sehr gut. Wir selbst sind der Beobachter. Das steht ja
hier oben, Implementsbeobachter. Das heißt, das Exemplar,
was hier gerade erzeugt wird, das soll der Beobachter sein.
Gut. Schauen, ob jetzt was passiert. Jetzt wollen wir erwarten,
dass da diese Meldung auf die Konsole geschrieben wird.
Wahrscheinlich sieht man die Konsole jetzt
gerade nicht
Ich gehe mal ganz kurz auf die Konsole.
Hier ist sie, es hat sich was Interessantes getan.
Ah, schon wieder das falsche Projekt.
Und die wird jedes Mal, wenn ich hier klicke,
seht ihr, wird sie wieder aufgerufen.
Teilweise sogar mehrfach. Interessant. Ich glaube, das ist nur ein Straw-Effekt.
Ich glaube, es ist in echt nur einmal.
Gut. Ja, was wollen wir denn dann machen?
Jetzt habe ich ja, glaube ich, schon den Quelltext gelöscht,
der da vorher stand oder habe ich ihn nur auskommentiert.
Ah, ich habe ihn zum Glück nur auskommentiert.
Wir müssen also diesen, diese Sache,
die wir hier irgendwie noch hart verdrahtet quasi gemacht hatten,
die nehme ich jetzt hier mal raus.
Weg damit
Und dann brauche ich den hier auch nicht mehr reinstecken.
Das ist ja auch ganz nett.
Und dann gehen wir mal wieder in unser Excel.
Und jetzt kriege ich diese Dependency weg. Jetzt weiß also,
das Sheet überhaupt nicht mehr, dass es diesen Magnefire gibt.
Gut. Ja, und jetzt kommt der Code eben hier
rein. Ich schreibe nur mal von Hand,
dass es nicht wie Magie aussieht. Also ich sage,
wenn was Interessantes passiert ist, das heißt,
jemand hat geklickt in diesem Sheet, dann sage ich diesen Magnefire.
Du sollst ja jetzt einen anderen Text darstellen.
Und welcher Text ist es? Ich frage das Sheet,
hey, sheet. Was ist denn dein aktueller?
Ach, das hat so viele getten Ton
Get very your get. Ich muss einmal ganz kurz in
die Klasse reingucken, wie ich das Ding genannt habe.
Das kriege ich jetzt nicht mehr auswendig hin.
Get selected Text. Also elected text. Tja,
schauen wir, ob das jetzt funktioniert.
Das sieht doch nicht schlecht aus,
oder?
Toll. Okay
Nochmal ganz kurz, was wir jetzt dadurch erreicht haben.
Also es ist jetzt erst mal komplizierter geworden. Wir hätten
vorher irgendwie eine Zeile Quelltext, die gesagt hat, okay,
der Magnetfire soll jetzt den Text ändern und da stand in der Skiklasse.
Und das war einfach. Wir haben es jetzt ein bisschen komplizierter gemacht.
Das ist fast immer so. Wenn ihr irgendwie sagt,
ich will es ein bisschen allgemein erfassen oder es soll nicht mehr so eng gekoppelt sein,
dann muss man meistens irgendwelche Abstraktionen dazwischen schieben.
Aber es lohnt sich hoffentlich langfristig. Warum lohnt es sich
jetzt? Weil dieses Sheet jetzt keine Abhängigkeit mehr zu Magnetfire,
diese Abhängigkeit war vorher da. Das war irgendwie blöd.
Das heißt also, wenn ich irgendwann, wie gesagt,
der Meinung bin, ich brauche den Magnetfire eigentlich gar nicht,
dann muss ich diese Klasse wieder anfassen.
Da muss ich die Tests dafür wieder anfassen,
will ich alles
gar nicht
Oder wenn ich irgendwann mal weitere Magnet Firewach,
habe ich ja schon gesagt, einer,
der es in Blau macht und einer ist Cousin,
macht einen anderen, der blinkt,
dann muss ich jedes Mal immer wieder diese Klasse anfassen,
will ich gar nicht.
Ich will einfach, dass diese Klasse sagt,
ein anderes Element wurde gerade selektiert,
falls es jemand interessiert, mach was mit dieser Information.
Und was wird mit dieser Information gemacht?
Also der beobachtet es in diesem Fall, dieses Excel.
Das fragt jetzt einfach nochmal ganz stumpf, okay,
worauf stehst du denn gerade? Was ist der aktuelle Text?
Holt sich den raus und gibt den dann dem Magnet Fire.
Und dadurch entstehen jetzt keine neuen Abhängigkeiten,
weil dieses Excel kennt ja sowieso alle drei anderen Klassen,
weil es die ja erzeugt und die sinnvoll in diese Gui
reinsteckt und so
Das ist doch ganz nett. Und diesen Overhead hier oben
habt ihr ja nur einmal pro Projekt. Ja, vielleicht
ganz viele Situationen, wo ihr dieses Beobachter musste einsetzt.
Und ihr werdet an dieses Interface und diese Klasse nicht jedes Mal neu schreiben müssen,
sondern die stecken in irgendeinem Paket, vielleicht Paket, Entwurfsmuster oder Paketbeobachter oder so.
Und dann könnt ihr das immer wieder verwenden. Ihr braucht
es nicht für jeden Anwendungszweck, neu zu schreiben. Gut. Okay,
jetzt sind wir noch nicht ganz fertig, denn wir wollten ja noch eine Sache,
dass hier unten diese Anzeige, die ihr jetzt nicht seht,
weil das mal wieder mit dem Beamer-Problem gibt, dass diese Anzeige sich auch aktualisiert.
Und in der alten Version war es jetzt so,
Ich bin dann einfach ganz stumpf in die Klasse Sheet
gegangen und habe dann hier unten eben reingeschrieben, okay,
ich habe erst den Megnifier gesagt, dass ich was machen muss,
dann muss jetzt eben auch noch diese Positionsangabe irgendwas machen.
Aber das haben wir jetzt ja schön aufgeräumt.
Ich brauche diese Klasse Sheet gar nicht mehr anfassen.
Was muss ich denn jetzt stattdessen machen?
Kann man eigentlich auch auf diese Design-Ebene diskutieren, ne?
Kann man das? Ja, wobei da jetzt nichts Neues dazukommt.
Also das Sheet, nochmal, ich wiederhole nochmal,
das Sheet sagt, das hat sich was getan.
Excel fragt, was ist der aktuelle aktuelle Text?
Und der wird dann an dieses Megnifier weitergeleitet. Ja,
und genauso kann ich jetzt auch sagen, okay,
ich lade nicht nur den Text an, Megnifier weiter,
den aktuellen,
sondern ich sage auch noch
der Position
Dass es jetzt mal was aktuelles machen soll. Wie aktualisiere ich überhaupt die Position?
Wir haben uns die Klasse ja noch gar nicht angeguckt.
Okay, also den Konstruktor kann man sich ja kurz angucken.
Also das heißt einfach nur, ich brauche drei Spalten,
weil hoffentlich wir nie mehr als 99 Spalten verwenden hier.
Also für diesen Text baue ich Deutsch Spalten.
Und ich kann es nicht ändern. Okay,
es gibt aber auf dieser Klasse sicherlich auch eine Methode,
wo ich sagen kann, ja,
Set-Text, das wird wahrscheinlich genauso sein wie da oben.
Okay. Das ist also hier
Also an dieser Stelle würde ich jetzt sagen,
ich will da die aktuelle Position reinschreiben.
Ich kann es ja vielleicht noch mal ein bisschen blöd machen oder
irgendwie so, wie ich es gar nicht haben will.
Also ich sage Position, Set,
Text und ich mache es einfach mal irgendwie Test.
Ich will einfach sehen, ob das überhaupt passiert,
ob sich da unten irgendwas ändert, wenn ich das ausführe.
Achtung, ich klicke? Ja, das funktioniert schon mal
. Das ist doch gut. Jetzt müssen wir nur noch
was Sinnvolles da reinschreiben. Wie kriege ich denn jetzt
was Sinnvolles? Schauen wir noch mal ganz kurz,
was man an diesem Sheet so alles abfragen kann.
F3 ist das in Eclipse
Wie dich das in mir gemacht. Ah, hier zum Beispiel,
seht ihr das? Ich kann zum Beispiel so einen Sheet fragen,
welche Reihe ist denn gerade selektiert und welche Spalte ist denn gerade selektiert?
Das kann ich genauso gut auch von außen fragen.
Das ist einfach eine Eigenschaft von solchen J-Tables.
Und diese Informationen brauche ich ja. Also mal kurz überlegen,
Callum ist quasi dieses Zwölf und Reihe, nee,
warte mal, nee, das ist das A, oder?
Callum ist das A und Ro ist dann zum Beispiel dieses Zwölf.
Okay. Ja, dann sage ich doch mal Sheet,
Get Callum, nee, das Get selected Callum hieß es
Ja, gets elected column. Und dahinter einfach gets elected
row. Wenn ihr euch gerade die Typen angeguckt habt,
in einer Autovervollstellung, werdet ihr merken, dass das nicht geht.
Aber das merkt sogar Eclipse. Also, gets elected column liefert euch ein Int zurück.
Und ich wollte jetzt irgendwie so eine String-Concordination machen.
Also ich mache das jetzt einfach mal hier so ein bisschen geschummelt.
Das ist jetzt auch nicht so 100 Prozent das, was passieren soll.
Seht ihr das da unten? 27, 211,
13, 114? Ah, ihr seht nichts, sorry.
Also hier oben, okay, 0-0,
das kann man noch verstehen und dann hier irgendwie, aha, 30, 2016.
Also wir werden einfach nur die Zahlen aneinandergeklebt.
Da entstehen Dinge, die man gar nicht malen darf.
Was ich ja stattdessen will, ist, ich will ja,
statt dieser Null will ich an A da stehen haben,
und statt diesem Eins würde ich ein B da stehen haben,
und hier soll C stehen, de.
Also ich muss irgendwie erstmal aus dieser Zahl einen Buchstaben machen.
Hat ja immer eine Idee, wie ich das machen kann.
Das aus Null wird ein A aus Eins und ein B
, aus Zwei und C. Das ist ja der Spital,
das ist auch ein B. Du denkst schon in die Zukunft,
was ist das, wenn wir mehr als 26 Spalt haben,
ich mache es jetzt mal ganz einfach,
ich nehme mal an, das geht maximal bis Z,
mir nicht
Und tot, das war 26. Das war die Umwelt,
das war dem Großart, dass du Schaas kombinierst.
Okay. Einzelne Arzt. Okay, also wir hatten gesagt,
oder du hattest gesagt, ich nehme also dieses Kalem,
ich glaube, das Motto der 26 lasse ich jetzt mal weg,
das ist nur für größere Spalten.
Und da hatte sie gesagt, ich muss das Große A
quasi drauf verdieren. Sehr gut. Und ich tue mir
das mal in eine Zwischenvariable, nenne ich das mal Spalten,
Name, das war ein ganz sprechender Name.
Oh, Typfehler
Ach so, weil Int und Schaa ist ja Int,
wenn ihr euch erinnert. Ich muss das explizit auf Chark casten.
Das mit der, dass mir das System auch glaubt,
dass es wirklich noch in den Schaa reinpasst.
Gut. Ja, und dann tue ich das doch mal hier.
Einfach davor, Spaltenname. So. Gucken, was da jetzt passiert. Naja,
Arnold, jetzt können wir uns noch die Frage stellen,
will man da wirklich eine Null stehen haben oder wenn eins für einen Benutzer nicht schöner?
Also ich glaube, das echte Excel fängt bei eins an, oder?
Ach, Entschuldigung. Aha, es tut mir leid,
ich vergesse das jedes Mal wieder. Also,
wenn ich hier raufklicke, dann stehe ich unten A null.
Ich finde, also irgendwie intuitiv vor Menschen,
das ist jetzt ja hier nicht für Programmierer gemacht,
diese Anwendung, wäre es ja vielleicht doch schöner,
wenn da eine Eins steht,
Also, dann führen wir doch nochmal einen dazu.
Und jetzt denke ich hoffentlich daran, dass ich es nach rechts schieben muss.
So. Und was stehen wir? Oh, huch. Was
ist das denn? Das ist ja merkwürdig. Ich wollte
, kann mir das jemand erklären? Hm. Was ist
denn jetzt los? Was habe ich da falsch gemacht?
Alle haben heute schon mal was. Du hattest noch nichts
. An den Stream wird ein Einswang gehängt, ne?
Also, nochmal ganz kurz, das ist ja ein Schar.
Wenn ich einen Charme mit einem String addiere,
dann wird der Char und der String
aneinander geklebt
Dann kommt ein weiteres Plus, da wird jetzt ein Int an den String rangeklebt.
Das heißt, dieser Ausdruck ist vom Typ String.
Und an diesen String tue ich dann noch mal die Einzelnen
dran kleben. Das heißt also, wenn ich will,
dass das Plus vorher ausgeführt wird,
das ist tatsächlich eine Intadition ist, dann muss ich dich klammern.
Durch Wiederholung aus SE1-Woche, 5 oder 6. So,
ich schiebe es wieder nach rechts, keine Angst.
Gut. A1, B1, 2, 3,
4. Ach, das sieht doch eigentlich alles ganz nett aus.
Dann machen wir noch mal den Test,
dass das da oben auch funktioniert.
Ach so. Das funktioniert immer noch. Ihr seht,
es funktioniert tatsächlich beides gleichzeitig. Ach, das ist doch
schön.
Jo. Gut
Ja, ich habe das jetzt ja schon mehrfach zusammengefasst.
Soll ich es nochmal zusammenfassen? Wir haben ja noch drei Minuten.
An diesem Diagramm hat sich jetzt nichts geändert, oder?
Nö. Was wir jetzt noch machen könnten,
was wir da ganz interessant wäre,
ich mache mal einmal ganz kurz eine Formatierung,
das ist alles schön formatiert ist, also erstmal organized Imports,
bitte steht noch nicht auf, ich habe noch was mit euch vor.
So, ich mache jetzt einmal ganz kurz einen Commit.
Wie macht man das in den Eclipse?
Commit? Und nennen wir das mal Sheet ist der Beobachter.
Okay, das war alles dazu
So. Und jetzt können wir uns überlegen,
ob wir in den letzten zwei,
drei Minuten noch die alternative Variante implementieren wollen,
wo ich sage, nein, nein,
ich will diesen Umweg nicht machen,
dass das Excel,
das Sheet beobachtet und dann Bescheid bekommt und dann wieder die Anfrage weiter delegiert an den Mettenfire und an die Position.
Wir könnten ja genauso mit sagen, der Mettenfire beobachtet direkt
das Sheet und die Position beobachtet direkt das Sheet.
Wollen wir das nochmal implementieren? Wir können nur eine Abstimmung machen.
Wer ist dafür, dass wir das implementieren? Okay,
einer wäre es dafür, dass wir es sein lassen?
Okay, das sind deutlich mehr. Okay,
ich zwinge euch zu nix, dann sehen wir uns
nächste Woche wieder