Wir beschäftigen uns jetzt heute mit der Übung zum Übungsblatt zum
letzten.
Was war denn die erste Aufgabe?
Naja, da gab es eine schöne Beschreibung für ein Zustandsdiagramm, in
dem bestimmte Sachen rauszulesen waren.
Hier sind jetzt erstmal die Übergänge zwischen den Zuständen
dargestellt.
Das heißt, wir haben so einen Zustand, dass eine Übungsaufgabe
irgendwie erstellt werden kann.
Es gibt also einen Übergang zwischen Zuständen, die irgendwie dieses
Erstellen modelliert.
Diese Aufgabe kann dann auch aktualisiert werden, nachdem sie erstellt
wurde.
Und sie kann auch wieder gelöscht werden.
Außerdem kann man Lösungen zu diesen Aufgaben einreichen.
Und es werden verschiedene Testfälle durchgeführt, wenn diese Lösung
eingereicht wurde.
Das Gelöscht hatten wir hier oben auch schon.
Hier oben war es die Aufgabe, die gelöscht werden kann.
Hier unten ist die Lösung, die gelöscht werden kann.
Das heißt, da waren zwei unterschiedliche Übergänge, die zu
modellieren waren.
Was gab es jetzt noch in diesem Text?
Wir hatten noch ein paar Bedingungen, die man sich dort anschauen
konnte.
Zum einen, dass die Aufgabe nur dann erstellt werden kann, falls sie
noch nicht existiert.
Das deutet auf sogenannte Garz hin, also Bedingungen für die
Zustandsübergänge, die wir gerade eben festgestellt haben.
Und sofern noch keine Lösung eingereicht wurde, kann sie auch
aktualisiert und wieder gelöscht werden.
Das heißt, das ist auch eine weitere Garz, die wir haben.
Eine etwas komplexere Geschichte ist das hier unten.
Alle Tests bestanden, wurden oder nicht.
Bedeutet eigentlich, dass hier zwei verschiedene Verzweigungen sind,
mit zwei unterschiedlichen Bedingungen, die erfüllt werden müssen.
Was haben wir noch?
Ja, jetzt schauen wir uns mal an.
Das sind vermutlich, oder die für uns erst mal dargestellten Zustände,
die wir jetzt modelliert haben.
Das ist aber auch nur eine mögliche Lösung.
Das heißt, es gibt verschiedene Möglichkeiten, wie sie dieses
Zustanddiagramm umgesetzt haben.
Die Tutoren sind auch angewiesen, dass sie dies, sofern es korrekt
ist, was sie dort modelliert haben, auch zulassen.
In unserer Modellierung ist es jetzt so, dass man eine Übungsaufgabe
erstellen kann.
Also das ist ein Zustand, den wir haben.
Wir haben einen Zustand gelöscht von einer Übungsaufgabe.
Wir haben einen Zustand Lösung eingereicht, was auch gleichzeitig, wie
Sie gleich sehen werden, der geforderte hierarchische Zustand ist.
Denn innerhalb dieser Lösung eingereicht, dieses Lösung eingereicht
Zustand, gibt es noch zwei unterschiedliche oder drei unterschiedliche
Zustände.
Einmal, dass eine Prüfung durch angestoßen wird und dass diese Prüfung
erfolgreich war oder auch, dass diese Lösung abgelehnt wurde.
Das sind jetzt erst mal die Zustände, die wir eigentlich jetzt
erwartet haben.
Es gibt aber auch noch andere Modellierungen, die vielleicht komplexer
oder andere Benennungen haben.
Das ist dann auch okay.
Was können wir jetzt noch hier rauslesen?
Wir haben jetzt hier noch das Lösung gespeichert und das gelöscht hier
unten.
Das sind Aktionen, die während eines Zustandsübergangs durchgeführt
werden sollen.
Das heißt, wenn man jetzt hier eine Lösung einreicht, dann soll
währenddessen die Lösung gespeichert werden.
Und das Löschen soll natürlich gleichzeitig auch dazu führen, dass die
Lösung, die man eingereicht hat, auch wirklich gelöscht wird.
Das heißt, dass diese Methode gelöscht aufgerufen wird.
Jetzt gibt es noch eine weitere Sache, die man hier noch rauslesen
kann.
Hat jemand eine Idee?
Oder sind wir schon nach den 15 Minuten?
Ja, eigentlich schon, ne?
Mist.
Sebastian, du hast zu lang gemacht.
Ich weiß nicht.
Gut.
Also, was haben wir hier noch?
Wir können noch die sogenannten Eingangsaktionen bestimmen.
Das sind diese gelben Sachen jetzt hier.
Die Empfangsbestätigung, die versendet wird, sobald man eine Lösung
eingereicht hat.
Das heißt, es ist ein Unterschied zu dem hier oben, was durchgeführt
wird, sobald man einreicht.
Denn diese Empfangsbestätigung wird erst dann versendet, wenn die
Lösung eingereicht wurde.
Das heißt, sobald man in diesen Zustand übergegangen ist.
Und die beiden, die Akzeptanzmeldung und die Fehlerlogdatei, die
versendet werden, sind jeweils die beiden Eingangsaktionen von den
Lösungen angenommen und Lösungen abgelehnt Zuständen.
Gut.
Und jetzt haben wir noch eine andere Sache, die, glaube ich, auch im
Forum kurz diskutiert wurde und nicht ganz klar war.
Das ist das hier unten.
Die Aufgabenabwicklung beendet.
War vielleicht nicht ganz klar formuliert, war aber bewusst so
gewählt, weil wir ein bisschen fordern wollten, dass sie da kreativ
werden.
Es gibt nämlich zwei Möglichkeiten, dies zu modellieren.
Entweder man macht das Ganze über ein direktes Beenden von der
Aufgabenabwicklung, also von dem gesamten Diagramm.
Oder man macht noch einen weiteren Zustand, der die Aufgabe gelöscht
darstellt und dann einen Epsilon-Übergang, der dann zu dem Endzustand
führt.
Das sehen wir aber gleich noch.
Gut.
Jetzt haben wir so ziemlich alles, was wir aus dieser Beschreibung
herauslesen können und wir schauen uns mal an, wie das Ganze jetzt
möglicherweise aussehen könnte.
Hier ist mal eine Lösung dargestellt.
Was sehen wir nun hier?
Wir haben jetzt die typischen Elemente eines Zustandsdiagramms,
Eingangsknoten und den Ausgangsknoten und dann Zustände dazwischen.
Jetzt haben wir hier einmal den Zustand Aufgabe existiert nicht und
dann den Übergang, dass es eine Aufgabe gibt, die existiert.
Und dann sieht man hier diese Guards, die ich eben schon beschrieben
hatte.
Das heißt, hier oben bedeutet das, dass dieser Übergang hier nur dann
aufgerufen werden kann, wenn die Lösung nicht existiert.
Wenn wir jetzt in diesem Aufgabe existiert Zustand sind, können wir
natürlich jetzt auch die Lösung einreichen.
Und jetzt sieht man hier auch die eben besprochene Aktion, die dann
ausgeführt werden soll.
Die schreibt man so darunter, dass die Lösung gespeichert werden soll,
während sie eingereicht wird.
Und hier, das ist jetzt tatsächlich ein bisschen schlecht lesbar,
sieht man für diesen hierarchischen Zustand, Lösung eingereicht, auch
eine Eingangsaktion, nämlich das Versende Empfangsbestätigung, was
ausgeführt wird, sobald man in diesen Zustand hinein gerät.
Was jetzt hier diese Hierarchie bedeutet, ist, dass, sobald man jetzt
in diesen Zustand eintritt, die Ausführung hier weitergeht, also man
sich erstmal in dem Prüfung ausstehend Zustand befindet, der wiederum
auch eine Eingangsaktion hat, nämlich, dass die Tests wirklich
angestoßen werden.
Und wir haben wieder zwei Bedingungen.
Einmal, dass die fehlgeschlagenen Tests gleich null sind, das heißt,
die Lösung wird angenommen.
Und wir können die Akzeptanzmitteilung versenden.
Oder aber auch, dass die fehlgeschlagenen Tests größer null sind.
Und dementsprechend mindestens ein Test fehlgeschlagen ist und somit
die Lösung abgelehnt wird.
Und wir das Fehler-Log versenden können.
Jetzt haben wir hier noch die Variante mit einem Aufgabegelöcht
-Zustand, der jetzt in dem Fall optional ist, weil man auch, wie
gesagt, noch eine andere Methode modellieren kann.
Benutzt man aber diesen Zustand, braucht man diesen Epsilon-Übergang.
Weiß jemand noch, was dieser Epsilon-Übergang ist?
Wer hat noch aufgepasst?
Wer weiß das noch?
Oder warum heißt der Epsilon-Übergang?
Der Kommiliton hat gesagt, es sei ein Übergang ohne Konditionen.
Was ist dann das Besondere daran?
Also dadurch, dass er keine Konditionen hat...
Okay, also worauf ich hinaus will, ist, dass er halt dann einfach
irgendwann erfolgen kann, sobald man in diesem Zustand ist.
Da es aber auch in diesem Zustand keinen anderen Übergang mehr gibt,
ist es klar, dass man von diesem Aufgabegelöcht-Zustand irgendwann zur
Beendung des Diagramms führt.
Kurze Frage, wer von Ihnen hat denn die Bonusaufgabe gemacht?
Wer fand sich schwer?
Okay, das Ergebnis habe ich erwartet, weil wenn man sich einmal die
Mühe gemacht hat, diese Aufgabe so zu modellieren, ist es tatsächlich
nicht mehr so schwer, den einen Punkt für die Bonusaufgabe abzuholen.
Denn was sollten Sie in der Bonusaufgabe tun?
Sie sollten diese Hierarchie auflösen.
Was muss man jetzt tun, um diese Hierarchie aufzulösen?
Naja, wir haben hier unten drei Zustände und man landet immer, wenn
man hier reinkommt, in diesem ersten Zustand.
Das heißt, wir müssen vermutlich diese Kante hier runterziehen und
müssen uns jetzt überlegen, was passiert, wenn man denn dieses
Entferne -Lösung aufruft.
Naja gut, da das bei allen drei gleich ist, landen wir einfach immer,
wenn wir Entferne-Lösung durchführen, wieder in dem Aufgabe-existiert
-Zustand.
Und das war eigentlich auch schon alles, was für die Bonusaufgabe zu
tun war.
Genau.
Gibt es... Ah ja, noch eine Sache muss man natürlich dann noch
modellieren, denn wir hatten ja eben diese Eintrittsaktion von dem
Lösung -einreichen-Zustand.
Die müssen wir jetzt natürlich dann auch an die Kante schreiben, weil
sonst würde diese nicht ausgeführt.
Das heißt, die Empfangsbestätigung müsste dann dort durchgeführt
werden.
Das modelliert nicht mehr so ganz das, was wir vorher beschrieben
haben, weil wir nicht mehr dieses Nach-dem-Einreichen haben, ist aber
trotzdem korrekt soweit.
Ja, also der Kommiliton hat gefragt, ob es nicht schöner wäre, diese
Empfangsbestätigung hier als Entry-Aktion für Prüfung ausstehen zu
machen.
Dann würde ich allerdings den Zustand umbenennen, weil das nicht mehr
dieselbe Semantik dann ist.
Ja, also kann man auf jeden Fall so machen.
Genau, wäre auch okay.
Gibt es sonst Fragen zu dem Zustandsdiagramm?
Da hinten, ja.
Die Frage war, ob man die Guards hier, Sie meinen wahrscheinlich die
beiden hier, ob man die braucht.
Ja, also prinzipiell kann es keine Lösung geben, wenn man hier oben
ist.
Aber wenn man das, was beschrieben wurde, modellieren will, braucht
man diese Guards.
Weil es könnte ja sein, dass jemand dieses Zustandsdiagramm erweitert
und dann entsprechend bräuchte man diese Information.
Also um es komplett vollständig zu modellieren, braucht man sie.
Um das zu modellieren, was im Text stand.
Sonst noch Fragen?
Ja?
Ja, gut, das hätte ich vielleicht nochmal erwähnen können.
Vielen Dank.
Also der Kommiliton hat gefragt, was bedeutet das Symbol hier jetzt
eigentlich?
Also davor ist das Logische nicht.
Also es existiert noch keine Lösung, bedeutet das Ganze einfach.
Für diejenigen, die das Zeichen noch nicht gesehen haben.
Einfach nur, damit es ein bisschen kürzer auf den Folien ist.
Ich hatte keine Lust, den ganzen Text da hinzuschreiben.
Ja, noch eine Frage?
Die Frage war, wie man jetzt explizit hätte darstellen können, dass es
mehrere Lösungen für eine Aufgabe gibt.
Das würde ein ziemlich anderes Diagramm erzeugen.
Dann hätten wir auch den Text ein bisschen anders schreiben müssen,
damit das funktioniert.
Es gab irgendeinen Grund, warum ich das nicht gefordert habe, weil es
kompliziert wurde.
Ich glaube, das geht jetzt auch ein bisschen zu weit für die Übungen
jetzt.
Aber man kann das modellieren, auf jeden Fall.
Es gibt aber jetzt keine Möglichkeit, das jetzt einfach in dieses
Diagramm reinzubauen, sondern man muss halt dann bestimmte andere
Sachen, bestimmte andere Zustände irgendwie erzeugen.
Aber schreiben Sie das mal ruhig im Forum, dann überlegen wir uns mal,
wie man das Ganze vielleicht umsetzt.
Wollt ihr noch irgendwas dazu sagen?
Ich soll fragen, wer es denn genau so gelöst hat.
Also genau so ist jetzt relativ, aber so ähnlich wie das hier.
Ja, das reicht schon.
Willst du noch was anderes fragen?
Dann mache ich einfach mal weiter.
Das war nämlich jetzt auch schon Aufgabe 1.
Jetzt kommen wir zu Aufgabe 2.
Der schönen syntaktischen Analyse mit Abbott.
Wem hat die Aufgabe Spaß gemacht?
Einer!
Hey!
Also uns hat sie auf jeden Fall Spaß gemacht, aber das haben wir ja
schon festgestellt, dass wir unsere Aufgaben toll finden.
Der Grund, warum wir diese Aufgabe gestellt haben, ist eigentlich so
ein bisschen zu motivieren, dass wir Ihnen zwar Möglichkeiten
anbieten, wie man zu einem Entwurf kommt, aber die Entwurfsentwicklung
selbst doch immer noch an Ihnen selbst hängt.
Das heißt, all diese Verfahren, die wir jetzt hier vorstellen oder die
wir genannt haben und auch diese Möglichkeiten, die man dort anwenden
kann, sind natürlich nur Annäherungen und sind auch wirklich nur als
Annäherungen zu sehen.
Das haben Sie wahrscheinlich gemerkt, als Sie das Ganze durchgeführt
haben, denn das, was da rauskommt, ist nicht unbedingt das, was Sie
modellieren würden, wenn Sie diese Aufgabe sonst gekriegt hätten.
Das ist so ein bisschen die Motivation, warum wir das gemacht haben.
Das heißt aber nicht, dass das jetzt keinen Lerneffekt hat, sondern
ein paar Sachen davon kann man schon übernehmen und wir schauen uns
jetzt mal an, was das Ganze ergeben hätte.
Wir hatten also diesen schönen Text hier.
Ein Professor beschäftigt sich mit mindestens...
beschäftigt mindestens einen wissenschaftlichen Mitarbeiter in seinem
Lehrstuhl und so weiter und so weiter.
Und man musste jetzt natürlich die ganzen Wortarten sich anschauen und
schauen, was denn da jetzt eigentlich drinsteckt.
In der Aufgabe A sollten Sie dabei ganz stupide einfach die Methode
von Abbott durchführen.
Das heißt, Sie sollten alles, was Abbott fordert, auch dort eintragen.
Das ist nicht immer sinnvoll und die Entscheidung, ob das dann nachher
auch modelliert werden soll, kommt dann in der Aufgabe B.
Aber für Aufgabe A sollten Sie in diesem Fall tatsächlich einfach das
machen, was in dieser Tabelle vorher stand.
Das heißt, schauen wir uns das mal an.
Zunächst einmal die ganzen Klassen.
Naja, das ist nicht so schwierig, denn fast alles, was großgeschrieben
ist und nicht am Satzanfang steht und nicht Sebastian, Martin oder
Tobias ist, sind mal einfach Nomen, die wir jetzt erstmal als Klassen
annehmen.
Das ist tatsächlich auch in den meisten Fällen erstmal eine gute...
oder eine hinreichende Bedingung, um Klassen in solchen Texten zu
erkennen.
Gut.
Was kommt jetzt noch?
Was hatten wir noch?
Wie eben schon gesagt, Sebastian, Martin und Tobias sind in diesem
Fall Namen nach Abbott, was auch in diesem Fall meistens korrekt ist.
Und wir sind in diesem Fall dann jetzt Exemplare von
wissenschaftlichen Mitarbeitern.
Was haben wir noch?
Wir haben die Assoziationen.
Das sind alle transitiven Verben, also Verben, die zwischen
verschiedenen Objekten eine Beziehung herstellen.
Das sind auch ein paar in diesem Diagramm.
Ich gehe die jetzt nicht alle durch, weil wir das gleich noch genauer
anschauen werden.
Willst du noch was sagen?
Notfalls.
Hast du Angst, dass ich...
Gut.
Machen wir mal weiter.
Jetzt kommt schon eine von den etwas quatschigeren Annotationen.
Denn diese Bedingung, die eben in der Tabelle stand, dieses Verb sein,
deutet auf eine Vererbung hin.
Ja, das kann sein, wenn man zum Beispiel sich anschaut, dass... wo
steht es?
Moment, ich muss mal grad gucken.
Da oben.
Nee, Quatsch.
Unten.
Übungsleiter sind wissenschaftliche Mitarbeiter.
In diesem Fall macht das Sinn.
Aber die beiden anderen Formen von sein sind in diesem Fall eigentlich
keine Vererbung.
Das schauen wir uns gleich aber noch genauer an.
Was gab es jetzt noch in diesem Text zu finden?
Wir haben gar nicht mehr so viel frei, wie man schon sieht.
Also so viel können wir gar nicht mehr annotieren.
Ja, wir haben noch zwei Formen von dem Verb haben, die ja auf
Aggregationen hindeuten sollen.
Und wir haben auch noch zwei Zusicherungen, nämlich Modalverben mit
müssen.
Außerdem...
Warum kommt da noch mal eine Assoziation?
Naja, da war auch noch eine Assoziation, die gefehlt hat.
Aber ansonsten, die Attribute, also alle Adjektive, die im Text
vorkommen, bedeuten auf Attribute hin.
Wobei auch das immer mit Vorsicht zu genießen ist, wie wir gleich noch
sehen werden.
Denn nicht alle diese Sachen sind wirklich Attribute von Klassen, die
wir modellieren wollen.
Gut.
Das war alles.
Hat jemand eine Frage dazu?
Ja?
Eigentlich schon.
Wenn man die Methode nach Abbott macht, eigentlich schon.
Ja?
Könnten Sie das ein bisschen lauter sagen, bitte?
Die Frage war, für welche Sprache die abbottische Methode konzipiert
wurde.
Naja, zuerst einmal für Englisch, aber es gibt auch eine adaptierte
Variante für das Deutsche, die wir zum Teil auch adaptiert haben.
Wenn man sich aber die Originalveröffentlichung anschaut, ist die für
das Englische gedacht.
Ja, noch eine Frage?
Die Frage war, wie es mit Botschaften aussieht.
Was haben Sie denn als Botschaft modelliert davon?
Hm?
Helfen.
Welches Helfen ist das?
Das Helfen wissenschaftlichen Mitarbeitern hier?
Oder haben wir noch eins?
Und Studierenden helfen.
In diesem Fall sind es keine intransitiven Verben, da sie einmal den
Studierenden helfen und einmal den wissenschaftlichen Mitarbeitern.
Das heißt, sie haben eine Beziehung, die hier dargestellt ist.
Nochmal?
Die Aussage war...
Ich habe sie immer noch nicht akustisch verstanden.
Okay.
Die Aussage war...
Haben Sie gesagt, dass es keine Akkusativobjekte sind?
Ja, das sind sie in diesem Fall auch nicht.
Aber das heißt nicht, dass es keine Beziehung zwischen ihnen gibt.
Man geht nämlich noch weiter, wenn es sich Beziehungen zwischen
verschiedenen Objekten anschaut.
Okay.
Zurück?
Auf die Abbot?
Okay, Moment, das dauert.
Also zum Beispiel hier die Beispiele Laufen und Schlafen würden keine
Beziehung zwischen dem Handelnden und einem anderen Objekt darstellen.
Das, was wir aber eben hatten, das Mithelfen, ist eine Beziehung
zwischen Professor und wissenschaftlichen Mitarbeiter oder eine
Beziehung zwischen den Übungsleitern und den Studierenden.
In dem Fall sind die Botschaften, die hier gemeint sind, aber Laufen
und Schlafen macht man nicht mit irgendjemand anderem.
Also man könnte schon mit jemand anderem laufen.
Dann ist es wieder...
Das war ein schlechtes Beispiel.
Aber wenn die nicht genannt sind, dann ist es intransitiv.
Gut.
Jetzt muss ich wieder hier drüber klicken.
Noch eine Frage, ja?
Wir können noch ein bisschen hin und her springen.
Das macht Spaß.
Die Frage Ihrer Kommilitonin war, diese Design-Verben, die wir eben
als Vererbung gekennzeichnet haben, sind keine Ist-ein-von oder Ist
-art -von.
Ja, das ist korrekt.
Hier hinten sind nur Beispiele genannt, die das abbilden.
Für die Abitur-Methode braucht man zunächst nur die Wortarten und die
Abbildung auf die Modelle.
Dieser Schritt, ob das jetzt wirklich eine Vererbung ist, machen wir
als nächstes erst für die zweite Aufgabe.
Das ist schon ein Schritt weiter und das ist genau das, was wir auch
erzeugen wollten.
Klar, gerade diese Vererbungen sind ja Quatsch.
Das wissen wir, wenn wir uns das anschauen, weil es keine Vererbungen
sind.
Aber Sie sollten zunächst einmal ganz stupide die Variante von Abitur
durchführen und dann diesen Übertrag machen.
Genau diese Idee, dass es halt das Nicht ist.
Das schauen wir uns jetzt aber auch noch genauer an.
Gut.
Noch einmal alles schön bunt.
Denn jetzt kommen wir dazu, wie führt man das Ganze jetzt in ein
Klassendiagramm oder überführt man das in ein Klassendiagramm?
Naja, schauen wir uns zunächst mal die Klassen an, die wir modellieren
wollten.
Wir hatten da mehrere Regeln in der Vorlesung, die uns angeben
sollten, welche Klassen wir jetzt wirklich modellieren und welche
nicht.
Eine davon ist, wenn sich keine Attribute oder auch Operationen
identifizieren lassen für eine Klasse, dann modellieren wir diese
nicht.
Außerdem, wenn es nur Operationen sind, die einer anderen Klasse auch
zuzuordnen sind, dann lassen wir diese Klasse ebenso weg.
Damit können wir schon mal einige der Klassen ausschließen.
Zum Beispiel den Lehrstuhl oder die Promotion, die keine Attribute
haben.
Auch die Semesterwochenstunden oder auch das Deputat oder das Datum.
Denn diese Attribute, die man da vielleicht modellieren könnte, waren
im Text nicht genannt.
Das heißt, wir modellieren diese Klassen erstmal nicht.
Außerdem, wenn eine Klasse nur ein einziges oder wenige Attribute
haben, so muss man prüfen, ob diese Attribute einer anderen Klasse
zugeordnet werden können.
Das haben wir jetzt im Fall von Teilnehmerzahl und Anzahl.
Denn hier sind die Attribute, die genannt wurden, so etwas wie
maximale Teilnehmerzahl, gewisse oder bestimmte Anzahl.
Das sind keine Attribute, die man modellieren möchte, sondern das ist
vielmehr ein zusammengesetztes Attribut, was man in einer anderen
Klasse modellieren möchte.
Gehen wir weiter zu den Assoziationen.
Da sollte man sich überlegen, welche dieser Objekte wirklich...
Das sind beides keine Klassen.
Also alle da genannten sind keine Klassen.
Also zunächst einmal war die Frage, ob wir die jetzt hier modellieren
und die hier nicht.
Wir modellieren beide nicht.
Also die hier unten nicht und die hier oben auch nicht.
Die andere Frage war, warum wir Inhalte nicht modellieren.
Ja, wir haben keine Attribute für Inhalte.
Das heißt, wenn wir die Regeln aus der Vorlesung anwenden, sollte
diese Klasse nicht modelliert werden.
Das lässt sich auch umsetzen, das sehen wir gleich noch, wie das geht.
Es ist nur nicht mehr, es gibt kein Inhaltobjekt mehr, das irgendwo
auftritt, sondern eine Vorlesung.
Wir lassen halt die Aggregation einfach weg, die dort beschrieben
wird.
Genau.
Gut.
Machen wir mal weiter.
Zwischen welchen Objekten liegen jetzt also dauerhafte Beziehungen
vor?
Also welche Assoziationen wollen wir uns anschauen?
Das sind jetzt alle, die im Text auftreten.
Beschäftigt an Lehrstuhl haben wir schon mal das Problem, Lehrstuhl
modellieren wir jetzt gar nicht.
Das heißt, wir haben die Klasse ausgeschlossen und können also diese
Beziehungen auch einfach nur über ein Attribut oder über eine
Operation und eine Assoziation darstellen bei einer anderen Klasse.
Genauso ist es bei diesen anderen.
Da gibt es keine Klassen.
Deswegen wird das Ganze zu einer Operation, die zwischen zwei anderen
Klassen passiert.
Und die anderen müssen wir auch noch modellieren.
Dann gab es noch die Geschichte mit den Aggregationen.
Also da sollte man überprüfen, ob es eine Rangordnung existiert, die
einen engeren semantischen Zusammenhang darstellen.
Wir hatten die möglichen Aggregationen.
Prüfungen haben ein Datum und eine maximale Teilnehmerzahl und jede
Vorlesung hat eine bestimmte Anzahl an Semesterwochenstunden.
Diese lassen sich in diesem Fall auch als Attribute modellieren.
Außerdem haben wir noch die Vererbungen übrig.
Das heißt, die Ist-Einbeziehung, die wir eben schon kurz angesprochen
hatten.
Und in diesem Fall ist natürlich nur Übungsleiter und
wissenschaftliche Mitarbeiter eine echte Vererbung, denn die anderen
sind keine, wie schon eben genannt, Ist-Einbeziehung.
Das heißt, die wollen wir nicht modellieren, sondern vielmehr als
Operationen darstellen.
Oder als Attribute in diesem Fall.
Dann haben wir noch die Attribute, die man sich anschauen muss.
Ist ein Attribut problemrelevant im Sinne der Systemanalyse?
Ja, also sind in der Lehre tätig, kann man als Attribut darstellen.
Und auch Deputat erfüllt.
Das heißt, daraus machen wir die Attribute tätig in Lehre und Deputat
erfüllt.
Und wenn wir jetzt all diese Regeln angewandt haben, können wir daraus
ein Klassendiagramm erstellen.
Das ist jetzt eine mögliche Lösung dieses Klassendiagramms.
Schauen wir uns mal kurz an, was es da zu sehen gibt.
Wir haben zunächst einmal den Professor, der, wie eben schon gesagt,
dieses Deputat erfüllt, Attribut hat und der eine gewisse Anzahl von
Semesterwochenstunden leisten kann.
Dieser Professor beschäftigt an seinem Lehrstuhl mindestens einen
wissenschaftlichen Mitarbeiter.
Wohlgemerkt, diese wissenschaftlichen Mitarbeiter kann man auch noch
anders modellieren, denn wissenschaftlich war ja eigentlich als
Attribut genannt.
Das heißt, es war auch vollkommen okay, eine Klasse Mitarbeiter zu
modellieren mit einem Attribut ist wissenschaftlich, vom Typ Boolean
zum Beispiel.
Genau, hilft bei Promotionen ist außerdem auch noch eine Beziehung,
die zwischen wissenschaftlichen Mitarbeiter und Professor existiert
und ein Professor hält eine Vorlesung.
Die Vorlesung hat eine Anzahl Semesterwochenstunden in Integer und
Inhalte, die jetzt als String dargestellt sind.
Ist vielleicht nicht unbedingt schön, man könnte dabei auch überlegen,
ob man eine Inhaltsklasse erstellen wollte.
Aber wir haben ja keine Inhalt für die Inhaltsklasse, deswegen ist es
schwierig, das zu modellieren in diesem Fall.
Dann gibt es noch die Vererbungsgeschichte zwischen wissenschaftlichen
Mitarbeiter und Übungsleiter und die drei Exemplare hier.
Die drei sind wissenschaftliche Mitarbeiter und sind in der Lehre
tätig.
Das heißt, man kann hier die Objekte auch noch hinzufügen,
unterstrichen in diesem Fall natürlich, weil es im Klassendiagramm
Objekte oder Instanzen immer unterstrichen werden.
Und wir haben noch die Prüfung, die von den Übungsleitern erstellt
wird, die ein Datum als Attribut hat und eine maximale
Teilnehmeranzahl.
Und die Studenten können halt Inhalte lernen, das lässt sich aber
allerdings entweder hier als diese Operation darstellen oder eben über
Assertion.
Das ist beides okay.
Und der Student kann noch an der Prüfung und an der Vorlesung
teilnehmen.
Das ist jetzt unsere Lösung für dieses Klassendiagramm.
Gibt es dazu Fragen?
Ja?
Die Anmerkung des Kommilitonen war, ist dieses Attribut Tätig in Lehre
wirklich eine sinnvolle Modellierung oder würde man nicht lieber ein
Ist tätig in von irgendwelchen anderen Objekten, die man halt
modellieren möchte in irgendeiner Form darstellen?
Ja, wenn man das Ganze ordentlich entwerfen wollen würde, ist das die
richtige Antwort.
Aber da es jetzt hier um das Anwenden der Methode ging, ist das
erstmal so okay.
Eine andere Modellierung wäre auch in Ordnung.
Ja?
Also, ich kann sie leider akustisch nicht verstehen, tut mir leid.
Sie wollten auf die Assoziationen hier oben hinaus und ob man dort die
Benennung der Assoziationen die Multiplizitäten, okay.
Der Default-Wert für Multiplizitäten ist 1.
Kann man aber modellieren, das ist okay, weil es keine Informationen
darüber im Text gab.
Das heißt, die einzige Multiplizität, die, glaube ich, exakt gegeben
war, war die hier oben im Text.
Die mussten sie natürlich modellieren.
Die anderen waren, glaube ich, nicht gegeben.
Die anderen sind optional.
Also, die Frage war, wenn wir jetzt den Default-Wert nehmen und da
steht halt nur 1, dann ist natürlich die Modellierung kaputt, weil ein
Student nur an einer einzigen Vorlesung teilnehmen könnte.
Natürlich, wenn sie das sinnvoll ergänzt haben und das ordentlich
gemacht haben, ist das natürlich nicht falsch und vollkommen sinnvoll,
das zu modellieren.
Bastian, willst du noch was sagen?
Ja, sehr gerne.
Die Abitur-Methode macht keine Aussagen über Multiplizitäten.
Dementsprechend haben wir das auch nicht gefordert.
Auch die da oben nicht, obwohl die im Text beschrieben ist.
Das heißt also, wenn sie nicht ganz quatschige Multiplizitäten gewählt
haben, dann ist das völlig in Ordnung.
Und wenn sie sagen, dass das im Text beschrieben ist, führt zu einer
komischen Multiplizität und deshalb mache ich das jetzt hier in meinem
Diagramm auch so, ist das auch okay.
Dass das anders sein sollte, als das beschrieben ist, vielleicht an
der einen oder anderen Stelle.
Ich weiß gar nicht, was war das Beispiel gerade eben mit einer
Vorlesung, glaube ich?
Wenn man hier zwischen Student und Vorlesung vorlesen jeweils eins
hat.
Dass man das so natürlich nicht modellieren wollte, ist klar.
Also wie gesagt, Multiplizitäten sind dieses Mal tatsächlich egal.
Insgesamt muss dieses Klassendiagram mit Vorsicht genossen werden,
denn es ist das Ergebnis der Abitur-Methode und auch der Umsetzung
unserer Regeln.
Man sieht aber schon, dass wenn man das Ganze wirklich sinnvoll
modellieren wollen würde, man sich vielleicht noch ein paar Gedanken
dazu machen muss, wie man das Ganze wirklich umsetzt.
Wir haben das von Ihnen nur so gefordert, damit Sie einmal diese
Methode anwenden und auch sehen, dass es Möglichkeiten gibt, Sachen zu
finden, aber nicht immer alle sinnvoll sind, die man dort
herauskriegt.
Das ist genau der Lerneffekt, den wir erzeugen wollten.
Ja, das geht auch so ein bisschen in die Richtung, was der Kommilitone
gerade eben gefragt hat mit Erweiterbarkeit.
Also dieses Klassendiagram, was Sie da jetzt gerade sehen, das
funktioniert halt genauso nur für diesen Text.
Also angenommen, wir würden sagen, dieser Text, der da steht, das ist
alles, was wir jemals mit dem System machen wollten.
Dann ist die Modellierung okay.
Wenn Sie da noch weiter darüber nachdenken und sagen, naja, es muss ja
irgendwie auch noch Inhalte geben oder man kann noch andere
Tätigkeiten haben, dann muss man das natürlich anders modellieren.
Das ist völlig richtig.
Aber wir sind jetzt hier immer davon ausgegangen, dass dieser Text
einfach die komplette Systemfunktionalität beschreibt und die sich
nicht ändert.
Da kommt dann dieses Diagramm dabei raus.
Ansonsten noch Fragen zu dem Diagramm?
Sonst würden wir mit der GUI weitermachen?
Ach ja, da gibt es noch.
Das ist noch die Einblendung für die Folien.
Gibt es da noch was?
Nee, du bist dran.
Martin schadet schon mit den Hufen.
Ja, ja, endlich.
Humor ist schon durch.
Ja, Humor ist durch.
Martin ist dran.
Gleich zuallererst.
Werden die GUI-Aufgabe überhaupt gemacht?
Ja, doch.
Nämlich alle.
Dann wäre meine zweite Frage.
Wer hatte davor schon mal eine GUI gemacht?
Einige.
Und jetzt die interessante Frage.
Wer denkt, dass es geklappt hat?
Ja, das sind die, die es schon davor gemacht haben.
Okay, aber doch einige, bei denen es geklappt hat.
Gut, wir hatten Ihnen einen Entwurf aus der Vorstandssitzung oder was
es war, Ihres Projektleiters gegeben.
War das hier auf der linken Seite.
Eine mühevolle Kleinstarbeit erstellt.
Es sind zwei Fenster drauf zu sehen.
Einmal so ein Hauptfenster.
Da waren noch so ein paar handschriftliche Anmerkungen.
Na, es soll irgendwie kein Vollbild möglich sein.
Das Fenster sollte in etwa 400x400 Pixel groß sein.
Es soll zwei Bildchen anzeigen.
Ein Vorschau- und ein Ergebnisbild mit maximal 150x150 Pixel.
Verzerrungsfrei.
Es soll zwei Knöpfe haben zum Laden von diesen Dateien.
Es soll einen Run-Knopf haben, der diese eigentliche Berechnung macht
und dann in einem neuen Fenster eben Zwischenschritte bzw.
das finale Fenster anzeigt.
Da gab es ziemlich viele Bonuspunkte dieses Mal.
Man konnte noch unten so einen weiteren Schieberegler machen, den man
dann zwischen den einzelnen Iterationen, den einzelnen Bildern, die
nach einer Iteration rauskommen, hin- und herhüpfen und die dann auch
getrennt speichern kann.
Idealerweise sieht es bei Ihnen dann später in etwa so aus.
Ein bisschen anders ist kein Problem.
Links oben und rechts oben eben das Originalbild und das finale Bild.
Wir haben hier diesen schönen Schieberegler mit den Grenzen, die wir
Ihnen vorgegeben hatten.
Und auch die Labels dazu, die dann anzeigen, wie die aktuelle
Einstellung ist.
Und hier haben Sie so ein zweites Fenster.
Da gibt es noch so einen Haken, den Sie einstellen können, dass Sie
auch die Updates entfangen wollen und diese Zwischenbilder anschauen
wollen.
Und rechts oben diesen Speichern-Knopf.
Was hier unten fehlt, ist dieser Bonus-Slider.
Der sitzt hier nicht.
Wenn Sie das Ganze jetzt mit Zwingen umsetzen wollen, brauchen Sie
sowas wie ein JFrame.
JFrame macht nicht sehr viel.
Das ist halt einfach das, was der Name sagt.
Das ist ein Rahmen, der einfach noch so einen Titel hat.
Und das war es auch schon im Großen und Ganzen.
Was er Ihnen bietet, ist so eine genannte Content-Pane.
Da können Sie die Dinger dann auflatschen.
Da können Sie sowas wie Labels, Slider einfach reinschieben.
Layout-Manager.
Mit denen können Sie dann auch sagen, wie das in etwa aussehen soll.
Und für das Zweite könnten Sie einen J-Dialog nehmen.
Einfach so ein Dialog-Menü wie man es kennt auch mit öffnen,
schließen, ja, nein oder halt eben so Dialog im Unterschied zu so
einem JFrame.
Einfach gebunden an einen JFrame und wenn der Dialog aktiviert ist,
kann man eben nicht auf diesen JFrame zugreifen, sondern der ist dann
auf jeden Fall im Fokus.
Können Sie aber auch mit einem JFrame lösen, wenn Ihnen das lieber
ist.
Geht aber auch mit einem JDialog und überlassen.
Ich würde jetzt mal ein bisschen reinzoomen.
Sie sehen schon, das sind grob drei Teile, die wir hier haben.
Oben für diese beiden Bilder, dann in der Mitte die beiden Slider und
unten die beiden Knöpfe.
Sie könnten beispielsweise J-Panel benutzen.
So einen Container für leichtgewichtige Dinge wie JLabel oder was Sie
da reinpacken wollen.
In dem Fall, ich habe es schon vorweggenommen, JLabel kann nicht nur,
wie der Name sagt, für Label, für irgendwelche Textsachen, die Sie
anzeigen wollen, verwendet werden, sondern mit JLabel können Sie auch
Bilder relativ einfach anzeigen.
Das heißt, Sie können jetzt, wenn Sie das so realisieren wollen, zwei
JLabel Elemente nehmen und die in so einen JPanel reinstecken und dann
noch halt mit irgendeinem Layout Manager sagen, naja, ich möchte sie
links und rechts nebeneinander haben und nicht oben oder unten haben.
Die Slider könnte man ebenfalls in so einen JPanel reinstecken.
Sie sehen schon, man kann das alles JPanels machen.
Können Sie aber auch anders machen.
Für die Slider an sich gibt es dieses JSlider Element,
beziehungsweise, was hier fehlt, diese JLabels, die vorne Iterations
und Samples anzeigen, gehören da auch dazu.
Für die Slider an sich können Sie ein bisschen JSlider machen.
Wie genau Sie das konfigurieren können, das sehen wir gleich auf einer
anderen Folie.
Und unten dann eben noch die zwei Knöpfe.
Gut, wie könnte sowas in Code aussehen?
Sie brauchen irgendwie eine Klasse, die eben von JFrame erbt.
Und dann können Sie da sagen, naja, okay, ich rufe da im Konstruktor
einfach mit irgendeinem Titel auf.
Dann haben Sie diesen schönen Titel oben in der Leiste.
Dann hat mir gesagt, oder dann hatte Ihr Manager, Ihr Projektleiter
vorgegeben, naja, es muss 400x400 Pixel groß sein.
Es darf nicht größer sein.
Man darf die Größe nicht ändern.
Auch vieles leichter macht.
Also muss ich auch irgendwie sagen, man darf es eben nicht ändern.
Und dann brauchen Sie irgendeinen Layout-Manager, mit dem Sie halt
sagen können, wie diese Elemente angeordnet werden sollen.
In unserem Fall diese drei JPanels übereinander.
Das können Sie beispielsweise mit so einem einfachen Box-Layout
machen.
Das sehen Sie hier in der Mitte.
Dieses Box-Layout können Sie dann noch sagen, naja, wir wollen das
entlang der Y-Achse haben.
Also wir wollen das übereinander.
Sie können jetzt auch sagen, Sie möchten es nebeneinander.
Dann können Sie die Achse auswählen.
Oder wie Sie es gerne möchten.
Aber das ist halt eins, was hier passen würde.
Es gibt noch mehrere.
Also Sie können auch Slow-Layout nehmen.
Oder Sie haben nicht gesehen, was es alles gibt.
Kein Problem, solange es halbwegs so aussieht, wie wir uns das
vorstellen.
Wir haben sogar den Vorteil, da wir ja gesagt haben, die Größe muss
nicht veränderbar sein, können Sie das sogar pixelgenau reinschreiben.
Sie müssten es ja nicht anders skalieren, wenn man es größer zieht.
Gut, da müssen diese drei Teile noch hinzugefügt werden.
Das haben wir hier schön versteckt in diesen drei Methoden.
Da würden wir Ihnen dann eine davon zeigen.
Wie könnte das aussehen?
Wir wollen da oben diese zwei Bildchen reinhaben.
Wir haben schon gesagt, wir brauchen so ein J-Panel Element.
Das würden wir uns hier auch machen.
J-Panel intern benutzt in unserem Fall einen Grid-Layout.
Grid-Layout können Sie sich vorstellen wie eine Tabelle.
Sie sagen einfach, wie viele Spalten, wie viele Zeilen Sie haben
wollen.
Dann können Sie sagen, in Zeile 2, Spalte 5 möchte ich jetzt das
Button -Element haben.
Das ist eine recht schicke Variante, wie Sie ein Layout machen können.
In dem Fall können Sie sagen, ich möchte hier ein Bild haben, hier
vielleicht nichts haben und hier wieder ein Bild haben.
Oder Sie sagen, ich möchte ein Rechteck zeichnen, der Größe 5, damit
ich irgendwie diesen Abstand habe.
Wie auch immer, Sie können das alles machen mit so einem Grid-Layout.
Was hier steht, das hat irgendwie Zeile 0 und 2 Spalten und 5 glaube
ich als Abstand zwischen den beiden Elementen.
Können Sie konfigurieren, wie Sie wollen.
Die maximale Größe können Sie aufsetzen.
Die Größe von so einem Bild soll ja maximal 150 Pixel sein.
Das heißt, wenn Sie beide wollen, brauchen Sie zweimal 150, plus noch
ein bisschen was in der Mitte.
Können Sie einstellen.
Wir haben das Ganze dann auch noch zentriert, weil das so gefordert
war auf dieser Spitze.
Können Sie aber auch hin und her schieben, wie Sie wollen.
Diese beiden Variablen, Preview Original und Preview Process, sehen
Sie hier jetzt in der Mitte nicht bei der Initialisierung, weil das
bei uns Instanz-Variablen sind.
Aber auch die, also die zeigen dann die Bilder an.
Das sind letztendlich diese zwei Tray-Label, die da gezeichnet sind.
Die kann man auch auf eine gewisse Größe einstellen.
Diese Preview Size ist bei uns einfach eine Typ-Dimension mit 150 bis
150.
Also damit sagen Sie einfach nur, wie groß diese Bilder sein sollen.
Ja, dann müssen Sie diese beiden Tray-Label-Elemente dem Panel
hinzufügen.
Das passiert hier unten.
Und ganz am Schluss müssen Sie dieses Panel auch, dieser Content
Paint, also diesem eigentlichen Tray-Frame-Container hinzufügen.
Was wir hier auch noch ein bisschen versteckt haben, ist dieses
Generate Preview.
Wie werden überhaupt diese beiden Trillchen geholt, erzeugt und auf
diese Tray-Label aufgemacht?
Das sehen wir auch in einem weiteren Schritt.
Ich glaube, jetzt haben wir erst den Preview Generator.
Genau, der macht dieses Vorschau-Bild.
Der macht die Berechnung von diesem kleinen Vorschau-Bild.
Der benutzt natürlich einen Filter, den Sie da übergeben.
Also diesen Filter, den Sie schon dokumentiert haben, der diese Fly
-Methode zur Verfügung steht.
Wir haben das Ganze mit Hilfe von Swing-Workern realisiert.
Swing-Worker sind so Hintergrund-Arbeiter, die irgendeine Arbeit
verrichten und wenn die Arbeit fertig ist oder wenn es ein
Zwischenresultat gibt, der GUI einfach Bescheid geben und sagen, du
ich habe da was für dich, möchtest du was damit machen oder nicht.
Hat den ganz großen Vorteil, die GUI friert nicht ein, während im
Hintergrund irgendwelche langwierigen Berechnungen laufen.
Wer von Ihnen hat den Swing-Worker benutzt?
Wer von Ihnen hat es nicht benutzt?
Ist Ihre GUI eingefroren?
Also bei wem ist die GUI eingefroren?
Okay.
Das ist natürlich auch ein gewisser Lerneffekt, der von uns gewollt
wurde.
Ich kann Sie beruhigen, wenn bei Ihnen die GUI einfriert.
Das ist kein Problem in der Bewertung, das ist für uns vollkommen in
Ordnung.
Vielleicht nur, dass Sie hier mitnehmen, es gibt so etwas wie Swing
-Worker, die im Hintergrund eben Arbeit machen und dafür sorgen, dass
die GUI entlastet wird, dass sie gleichzeitig mit der Maus arbeiten
können, dass sie irgendwo rumklicken können, ohne dass das ganze Ding
eingefriert.
Aber das hatten wir Ihnen natürlich vorher so nicht gesagt.
Die Frage war, wie der Vorteil gegenüber Threads ist.
Im Endeffekt sind es Threads, die im Hintergrund laufen.
Das Konzept der Fäden haben Sie allerdings deutlicherweise nicht
kennengelernt in der Vorlesung.
Für Swing benutzt man normalerweise Swing-Worker, aber das sind
Hintergrundfäden.
Im Endeffekt sind es Threads.
Ich verstehe den eigentlichen Kern Ihrer Frage glaube ich noch nicht
sehr.
Also die Frage zielt ab, inwiefern das schwieriger ist, wenn man
keinen Swing-Worker verwendet.
Wenn Sie keinen verwendet, dann sind Zwischenergebnisse ein Problem.
Es kann sein, dass das ganze Fenster erst gezeichnet wird, um die
Rechnung zu fertigen.
Meinen Sie das?
So halb.
Okay, wenn es die Lösung war, dann...
Also Swing-Worker sind immer dann gut, wenn Sie halt längere
Berechnungen haben.
Wenn Sie nur kleine Berechnungen haben, brauchen Sie die nicht
unbedingt.
Ich würde es der Klasse weiter erklären, wenn keine weiteren Fragen
sind momentan.
Okay, also so ein Swing-Worker bietet ein paar Methoden, die Sie
überschreiben müssen.
Die eigentliche Arbeit wird in diesem Doing-Background gemacht.
Dort sagen Sie, was im Hintergrund an Arbeit stattfinden soll.
In dem Fall würde er diesen Filter, den Sie da im Konstruktor
übergeben haben, aufrufen und würde einfach sagen, er zeugt mir hier
dieses Vorschau-Bild mit der gewissen Anzahl an Iterationen und
Samples, die wir vorgegeben hatten.
Ich glaube, nur die Iterationen bei 30 Samples oder so.
Dann macht er das und wenn der Background-Worker fertig ist, der Swing
-Worker fertig ist, ruft er hier dieses Done auf und dieses Done sorgt
dafür, dass eben auf diesem J-Label, auf diesem rechten J-Label das
ist das Preview-Process, das ist der rechte J-Label auf dem Set-Icon,
New -Image-Icon aufgerufen wird.
Das heißt, ich zeichne mir hier ein neues Bild und dieser Get-Aufruf,
der holt sich eben das Ergebnis von dort, macht es hier drauf und dann
wird das Ganze halt angezeigt.
Eine relativ einfache und elegante Methode, wie Sie das Ganze
berechnen und in so einem J-Label anzeigen können.
Als nächstes die Slider.
Wie kann man so Slider implementieren?
Gut, Sie brauchen vorne ein bisschen Text, also diesen Label haben wir
in diesem Iter-Label drin, das ist auch wieder eine Instanz-Variable.
Gut, da möchten Sie irgendwie sagen, wie viele Iterationen gerade
eingestellt sind.
Das können Sie ganz einfach setzen.
Und dann kommt der eigentliche Teil dieser Slider.
Dieser Slider hat ein paar Attribute.
Sie können sagen, von wo bis wo gilt das.
Wir hatten irgendwie eine 2000 hier vorgegeben.
Also geht er von 0 bis 2000 und Sie initialisieren den auf einen
gewissen Wert.
In dem Fall, ich glaube, die 100, die wir als Default-Wert drin
hatten.
Können Sie aber auch, glaube ich, machen wie Sie wollen.
Dann gibt es ein paar Attribute.
Sie sehen auf dem Screenshot, den wir Ihnen gegeben hatten, wir
möchten das Ganze irgendwie in 500er Schritten haben.
Können Sie mit diesem Set Major Tick Spacing einstellen.
Und Sie sehen, dass wir sowohl die Zahl unterschreiben, als auch hier
diese Trennstriche zwischen diesen Major Ticks machen.
Das können Sie mit diesen beiden Methoden so setzen.
Habe ich mal kurz dazwischen gerät.
Zwei Hinweise, das war nicht gefordert.
Ich weiß nicht, ob du das gerade gesagt hast.
Dieses Tick Spacing, das war bei uns noch zusätzlich mit dabei, weil
wir gesagt haben, sieht hübscher aus, aber das war nicht gefordert.
Und die Standardwerte waren auch nicht frei zu wählen, sondern die
waren auch vorgegeben von uns.
Also 130 sollte da schon stehen.
Wunderbar.
Ich bin ja aus dem Off, hat es klargestellt.
Was noch interessant war, was soll passieren, wenn jemand mit diesem
Slider rumspielt?
Dazu gibt es diesen Chainschlüssner, den Sie anpassen müssen,
schreiben müssen.
Es gibt hier dieses Day Changed, also wenn der Zustand dieses Sliders
geändert hat, was soll dann passieren?
Naja, man wartet, bis jemand fertig ist mit Rumspielen.
Also nicht sobald einer drauf geht und hin und her geht, sondern
sobald einer etwas ändert und dann wieder loslässt.
Das können Sie hier mit diesem Slider, sobald er nicht mehr adjustiert
wird, ändern, erreichen.
Dann möchten Sie jetzt diese neue Zahl an Iterationen speichern, damit
Sie sie später für Ihren Filter verwenden können.
Und Sie möchten hier diesen Label natürlich anpassen auf den neuen
Wert.
Passt?
Wunderbar.
Gibt es Fragen zu diesem Slider?
Beide funktioniert natürlich genauso.
Okay.
Dann haben wir hier den Load-Topf, der jetzt einfach so ein Bild laden
soll.
Wir haben das Ganze hier auf zwei Folien, weil dieser Action-Performed
-Teil nicht mehr auf die Folie gepasst hat.
Im Großen und Ganzen machen Sie sich einen neuen Button und auch hier
müssen Sie in so einem Action-Listener sagen, was soll passieren, wenn
jemand auf diesen Knopf drauf drückt.
Stehen wir auf der nächsten Folie.
Wenn Sie die Bonusaufgabe, die letzte Bonusaufgabe, glaube ich,
gelesen haben, sollten Sie so Hilfstext erstellen, der angezeigt wird,
sobald man über einen Knopf drüber geht.
Das ist letztendlich eine Zeile, die Sie da hätten reinschreiben
müssen.
Die Sie reinschreiben mussten, wenn Sie es getan haben.
Jeweils pro Knopf natürlich.
Also Sie können das Ganze als Tool-Tipp machen.
Dann wird das an dem Knopf angezeigt, wenn Sie mit der Maus drüber
gehen.
Die eigentliche Action-Performed-Methode sieht so aus.
Sie sollten jetzt einen Dateidialog erstellen, der eben eine
Ladefunktionalität für Bilder bietet.
Das heißt, Sie erstellen sich als erstes so einen J-File-Juicer und
dann müssen Sie den noch ein bisschen anpassen.
Wir hatten gesagt, er soll nur mit PNG-Dateien arbeiten.
Das heißt, Sie müssen da so einen File-Filter benutzen, der dafür
sorgt, dass halt kein JPEGs oder andere Bilder geladen werden können.
Hier müssen Sie die Sachen anpassen, wohl oder übel.
Man kann auch ausstellen, dass dieses Werden-Alle-Annehmen angezeigt
wird.
Das können Sie mit dem da machen.
Dann müssen Sie sagen, dass nur Dateien zulässig sind und nicht auch
ganze Verzeichnisse.
Und dass man auch nicht mehrere Dateien auf einmal auswählen kann,
weil das unterstützt die Implementierung nicht und die
Einschränkungen, die Sie da noch machen müssen.
Dann müssen Sie den Dialog natürlich irgendwie noch anzeigen.
Das passiert hier in diesem If.
Er wird angezeigt.
Hier ist er an das Button-Element gekoppelt.
Das muss man glaube ich nicht machen.
Er wird angezeigt und sobald der Benutzer auf Proof klickt, wird eben
hier dieses neue Bild gesetzt.
Dieses Bild als neues Originalbild gesetzt.
Ihr vorhandenes Dummy-Bild quasi überschrieben.
Und es wird dann hier wieder Generate Preview aufgerufen, was eben
diese beiden Bilder berechnet und einzeigt, was ich vorher schon
erwähnt habe.
Gibt es Fragen zu diesem Knopf?
Dann ist das hier die zweite Ansicht, die Sie machen sollten.
Da gibt es links oben diese Checkbox für Continuous Updates, wie wir
es genannt hatten.
Rechts oben diesen Speichern-Knopf und die Bonusaufgabe da unten noch
so ein Slider vor.
Und in der Mitte möchten Sie halt eben die einzelnen Iterationen bzw.
finale Bilder zeigen.
Auch hier brauchen Sie wieder eine Klasse.
Ihr erbt jetzt in diesem Fall von JDialog.
Ich habe schon gesagt, Sie können das auch als JFrame machen, wenn
Ihnen das lieber ist.
Dieser JDialog wird dieses Super-Main wird eben an einen JFrame
gekoppelt.
Und erst wenn ich diesen Dialog schließe, bin ich wieder bei diesem
JFrame.
Was wir da letztendlich in dieser Klasse alles machen, wir erholen uns
dieses Originalbild, wir erstellen uns den üblichen Random-Point
-Generator, den wir halt brauchen.
Dann machen wir uns hier einen Filter.
Sie sehen schon, der heißt bei uns nicht mehr Triangle-Picture-Filter,
sondern Observable-Triangle-Picture-Filter, weil wir das versucht
haben mit einem Beobachter umzusetzen.
Der Beobachter, Sie sehen hier auf Filter.AddObserver der kann hier
diesem Filter, diesem Observable-Triangle-Picture-Filter hinzugefügt
werden.
Dieser Beobachter hat die eine Aufgabe, sobald ein neues Bild erzeugt
wurde, also eine neue Iteration eines Bildes erzeugt wurde, also ein
neues Zwischenresultat, soll das direkt auf der GUI angezeigt werden
können.
Dazu muss man diesen Triangle-Picture-Filter anpassen.
In Ihrer normalen Implementierung sorgt er dafür, dass er Ihnen ein
finales Bild zurückgibt.
Hier wollen wir aber nicht das finale Bild haben, sondern wir möchten
nach jeder Iteration, also wenn er alle 30 Samples durchgemacht hat,
möchten wir das eine Iterationsbild haben und anzeigen können.
Das heißt, wir müssen die Apply-Methode entsprechend anpassen.
Und in dem Fall wollen wir auch noch einen Beobachter haben.
Das heißt, wir brauchen auch noch eine Funktionalität, um einen
Beobachter hinzuzufügen, zu löschen und aktualisieren zu können.
Auch hier wieder Layout setzen und eben diese Blöcke hinmachen.
Sie sehen hier bei AddObserver ein Prozessorelement übergeben.
Auch bei uns wieder eine Instanz-Variable.
Das ist einfach das, was die Berechnung anstößt, die die Ergebnisse
entgegennimmt und dann der GUI präsentiert.
Das sehen wir aber gleich auch.
Hier erstmal die Anpassung, die wir bei unserem Observable Triangle
Picture Filter gemacht haben.
Zum einen diese beiden Methoden AddObserver und RemoveObserver, um
eben diese Observer hinzufügen zu können, wegzumachen.
Und was wir hier machen, immer wenn ein Iterationsschritt komplett
ist, rufen wir eben alle Observer, die sich registriert haben, an
unserem Observable Triangle Picture Filter auf und sagen, sie sollen
ihre Methode Update mit eben diesem neuen Bild aufrufen.
Dann können die Observer eben in der GUI sagen, okay, das Bild möchte
ich jetzt bezeichnet haben.
Genau.
Die Observer können auch gespeichert werden.
Ich zeige Ihnen noch eine weitere Folie.
Sie wird aufgeschrieben, wenn der Grundschritt beendet ist.
Kennen Sie diese Darstellungsweise?
Wer kennt die?
Möchte Sie jemanden erklären?
Wie eine Vorschleife, nur schöner und in einer Zeile.
Also Sie sagen, man geht jeden Observer durch, den wir hier oben
gespeichert haben und rufen darauf einfach Update auf.
Es spart Ihnen einfach jede Menge Schreibarbeit.
Hier vorne sehen Sie, Sie gehen über die Observers und gehen jedes
Element, was eben in dieser Liste drin ist und für jeden Observer, den
Sie dort finden, rufen Sie dort eben Update auf.
Das ist nur, damit Sie es mal gesehen haben.
So kann man das Ganze bequem machen.
Sie können natürlich aber genauso gute Vorschleife finden.
Der Image Prozessor, also das war dieser Prozessor, den wir da
übergeben hatten als Observer.
Der implementiert hier die Schnittstelle PictureFilterObserver.
Das ist also eben genau so ein Observer, der sich dort registrieren
kann und darf.
Sie sehen, der ist auch wieder als SwingWorker implementiert.
Hat also auch wieder diese zwei Methoden DoingBackground und Done.
Was macht der?
Naja, seine Hintergrundarbeit ist, er ruft auf diesem Filter einfach
auf mit dem Original Bild und dieser momentan eingestellten Anzahl an
Iterationen und an Samples, dass das Ganze getan werden soll.
Und sobald er fertig ist, also komplett fertig ist, alles komplett
berechnet ist, holt er sich das Ergebnis und setzt eben Preview auf
das Ergebnis und zeigt das Ganze an und sorgt auch dafür, dass man ab
sofort speichern kann.
Das hatte ich Ihnen gesagt.
Genau.
Noch eine weitere Folie.
Es gibt bei SwingWorkern auch die Möglichkeit mit Process und die
Update -Methode kommt vom PictureFilterObserver.
Es gibt noch die Möglichkeit mit Process zu sagen, was passieren soll
mit Zwischenresultaten.
Also ich hatte Ihnen gesagt, SwingWorker kann im Hintergrund nicht nur
ein Ergebnis berechnen und das dann zurückgeben, sondern es kann auch
Zwischenergebnisse berechnen.
Zum Beispiel kann man sagen jedes Mal
jedes Mal wenn es ein Zwischenergebnis gibt und ein Update jedes Mal
wenn ein Update aufgerufen wird und es ein neues Zwischenergebnis
gibt, kann man das mit Publish eben an diese Prozess-Methode schicken
und die Prozess-Methode kann dann machen, was immer sie will.
Also Update würde hier Zwischenergebnisse entgegennehmen, würde sie an
Process weiterleiten.
Process würde jetzt hier eben jedes Mal das letzte Bild, das es
bekommen hat, eben einzeichnen und so haben Sie immer diese neuen
Iterationsschritte.
Fällt Ihnen etwas auf bei dieser Obachter-Implementierung?
Wer ist noch wach?
Einer winkt.
Das war zum Thema wach, oder?
Wer ist wach und will etwas sagen?
Okay.
Ja stimmt, wer nicht wach ist, kann nichts sagen.
Irgendwo ist halt immer der Fehler.
Ja, kurz und gut, unsere Beobachter-Implementierung ist kaputt.
Wir werden die nachbessern und Ihnen zur Verfügung stellen.
Wobei, wenn es keiner von Ihnen gemerkt hat, hätten wir es eigentlich
auch so lassen können.
Warum?
Dieser Image-Prozessor löst das Ganze an, will aber gleichzeitig auch
der Beobachter sein, der das Ganze entgegennimmt und
weiterverarbeitet.
Das heißt, das Ding ist eigentlich nicht sauber getrennt.
Sollte man in der Form nicht machen.
Da wir das heute Morgen kurz vor der Übung festgestellt haben, haben
wir die Folien jetzt nicht mehr geändert.
Wir werden das noch korrigieren und natürlich auch den Code noch
korrigieren.
Werden Ihnen dann die aktuelle, bessere, schönere Version schlagen.
Aber die Idee an sich bleibt, dass Sie einen Observer nehmen, der
einfach diese Zwischenschritte weiterreicht und die dann in der GUI
zeigt.
Also Beobachter-Entwurfsmuster dafür.
Jetzt kriege ich schon Signale, dass ich mich ein bisschen beeilen
soll.
Was haben wir hier?
Das hatten wir schon.
Dann noch, wie Sie so eine Checkbox-Update-Variante machen können.
Sie brauchen auch hier zu Ihrer Checkbox so einen Action-Listener, der
sagt, diese Checkbox oben mit Continuous Updates.
Was soll passieren, wenn jemand draufklickt?
Wenn jemand draufklickt und die ist jetzt ausgewählt, also er klickt
drauf und jetzt ist der Haken dran.
Naja, dann will ich einen Observer haben, der mir eben diese
Zwischenresultate entgegennimmt und sie anzeigt.
Auf der anderen Seite, wenn jemand den Haken wegmacht und eben nicht
diese Continuous Updates empfangen will, dann mache ich einfach nur
diesen Observer weg und dann habe ich keinen mehr, der mir das Ganze
anzeigt.
Das ist eine relativ elegante Variante.
Dann sind wir schon bei einer Bonus-Aufgabe.
Da gehe ich mal ein bisschen schneller drüber.
Sie sollen Bilder verkleinern, wenn sie über 1024 x 768 Pixel sind.
Sie fragen erst nach, ob das der Fall ist.
Dann fragen Sie den Benutzer nach mit einer Nachricht, möchtest du das
überhaupt machen?
Wenn er sagt, nö, möchte ich nicht, dann machen Sie gar nichts,
springen wieder raus.
Wenn er sagt, ja, möchte ich machen, dann können Sie z.B.
auch die JMJ-RSD-Version mit Resize benutzen.
Die macht das Ganze für Sie.
Wenn er es eben nicht wollte, dann können Sie das Original behalten.
Da war glaube ich jetzt nicht so viel.
Dann gebe ich dir noch 4 Minuten für Aufgabe 4.
Wenn Sie Fragen haben, dann halt leider über das Forum.
Ich habe noch eine Frage.
Vermisst jemand was in unserer Musterlösung?
Also ich vermisse da was.
Und zwar haben wir jetzt hier die andere Bonus-Aufgabe für 5 Punkte
nicht vorgestellt.
Wir reichen das nach.
A.
Aus Zeitgründen.
B.
Weil wir auf dem neuen Übungsblatt eine Frage dazu haben.
Wenn wir jetzt unsere Musterlösung zeigen, dann beantworten wir damit
die Frage.
Wäre ein bisschen blöd.
Dementsprechend müssen Sie da bis zur nächsten Übung warten, bis Sie
da die Musterlösung sehen.
Es gab noch eine letzte Aufgabe auf dem Übungsblatt und die war zum
Geheimnisprinzip.
Ich hatte Ihnen ja schon in der Vorlesung angedroht, dass Sie sich
dazu zwingen, sich da mal Gedanken drüber zu machen.
Wer hat denn die Aufgabe bearbeitet?
Sehr schön, so wollte ich das sehen.
Also für alle YouTube-Schauers, es melden sich gerade alle.
Ist ja auch deine Aufgabe.
Ich wollte unbedingt, dass diese Aufgabe gemacht wird und habe deshalb
auch extra viele Punkte dafür verteilt, damit Sie sich eben genau mit
dem Geheimnisprinzip auch mal beschäftigen und da extrinsisch
motiviert werden.
Und dann hinterher hoffentlich erkennen, dass das sinnvoll war.
Gut, was sollte getan werden?
Naja, als wir uns die Aufgabe ausgedacht haben, war es gerade heiß und
wir hatten keine kalten Getränke.
Und dann sind wir auf die Idee gekommen, so einen Kaltgetränkeautomat.
Den bräuchte man doch eigentlich mal.
Und wir haben Ihnen eine kleine Beschreibung dazu mitgeliefert, wie
denn der Beginn einer Implementierung eines Kaltgetränkeautomats
aussehen könnte.
Und in dieser Beschreibung geht es erstmal nur darum, dass der
Getränkeautomat entweder an oder aus sein kann.
Offensichtlich muss es noch weitergehen, weil nur mit an und aus habe
ich noch keine kalten Getränke, insbesondere wenn er aus ist.
Auf jeden Fall war das mal so der Beginn.
Und dazu haben wir Ihnen noch eine Implementierung mitgeliefert, wie
man sowas denn anfangen könnte zu implementieren.
Das war diese hier.
Und dann waren drei Fragen dazugestellt.
Die erste war, wo wird denn das Geheimnisprinzip verletzt?
Was sollte denn eigentlich verborgen werden?
Und die letzte Frage war dann, ja, machen Sie es doch gerade mal
besser.
Ich gehe da jetzt mal schneller drüber.
Erster Hinweis, dass da oben nicht die Antwort auf dort wird das
Geheimnisprinzip verletzt.
Also ja, das ist Public, aber das ist kein Problem, denn das sind
einfach Konstanten.
Die könnte man hier auch privat machen, ja.
Aber das ist nicht das eigentliche Problem.
Das wirkliche Problem hier sind die Getter und Setter.
Und zwar deshalb, weil wir gesagt haben, Entwurfsentscheidung ist, der
Automat kann entweder an oder aus sein.
Und nicht, wir setzen mit Integer irgendwelche Zustände.
Das heißt also, wir haben hier in dieser Implementierung eben genau
diese Entwurfsentscheidung nicht verborgen.
Das heißt, wir sind, wenn wir diese Implementierung benutzen, immer
daran gebunden, dass der Status über Integer modelliert wird.
Deshalb sollte man das korrigieren.
Und ich habe Ihnen hier eine Lösung mitgebracht.
Wie gesagt, man kann hier oben die Statuskonstanten auch privat
machen, weil die braucht man dann irgendwie von außen nicht mehr.
Kann man aber auch public lassen.
Das verrät nichts über die interne Implementierung.
Und was man dann tun kann, um der Beschreibung zu entsprechen, ist
einfach Mache an und Mache aus Methoden anzubieten, die eben den
Automat anmachen, ausmachen und eine Boolshe Methode, die eben verrät,
wie denn der Zustand ist des Automaten.
Und dann müssen Sie nur geringfügige Anpassungen in Ihren Methoden
machen und wie Sie hoffentlich sehen und erkennen, ist es jetzt völlig
egal, wie Sie den Zustand intern modellieren.
Ob Sie jetzt statt Integer plötzlich eine Boolshe gutes Attribut
benutzen oder ob Sie noch besser eine Aufzählung benutzen, ist völlig
egal.
Weil Sie haben nach außen nur noch diese Methoden sichtbar und das
funktioniert für jedwede interne Implementierung.
Und jetzt bin ich genau auf dem Punkt fertig.
Gibt es noch eine Frage?
Für eine hätten wir noch Zeit.
Da kommt eine.
Ihr Kommilitone sagt, man könnte doch einfach auch eine Methode
machen, die den Zustand einfach nur ändert.
Ich weiß nicht, was Sie da gesagt haben.
Das ist, glaube ich, auch okay.
Das finde ich persönlich nicht so die richtig schöne Variante.
Insbesondere, wenn man dann mal drüber nachdenkt, man möchte das
vielleicht mal noch erweitern.
Man möchte noch einen dritten Zustand haben, dann möchte man das so
nicht haben.
Aber ja, das löst das Problem auch.
Gut.
Dann sind wir durch.
Doch, noch eine Frage.
Sie müssen sich noch kurz gedulden.
Genau.
Wenn Sie den Zustand per Inem setzen und zurückgeben, dann verletzen
Sie das Geheimnisprinzip ja eigentlich auch.
Dann sind Sie halt auch darauf festgelegt, dass Sie das immer mit
einem Inem machen wollen, müssen.
Deshalb haben wir das so nicht gelöst.
Genau.
Gut.
Dann sind wir durch.
Wunderbar.
Schönes Wochenende.