WEBVTT

00:07.540 --> 00:10.420
Herzlich willkommen zur Vorlesung Software-Technik 1.

00:11.520 --> 00:14.140
Ich würde gerne mit dem Puzzler für heute anfangen.

00:14.420 --> 00:15.640
Bitte kommen Sie ein bisschen zur Ruhe.

00:15.920 --> 00:16.400
Danke schön.

00:17.480 --> 00:19.320
Auch heute wieder ein kleines Java-Rätsel.

00:19.660 --> 00:21.820
Das sieht erst mal relativ überschaubar aus.

00:22.620 --> 00:26.200
Wir haben eine Klasse und eine Hauptmethode.

00:26.980 --> 00:27.720
Mehr brauchen wir nicht.

00:28.400 --> 00:30.620
Und hier gibt es einen Zufallszahlengenerator.

00:30.860 --> 00:34.980
Der wird statisch angelegt und der wird auch schon initialisiert.

00:36.420 --> 00:36.820
Instanziiert.

00:37.440 --> 00:42.940
Und in der Hauptmethode wird jetzt über eine Zufallszahl ausgewählt,

00:43.040 --> 00:48.360
ob man einen Stringbuffer mit P, mit G oder mit M initialisiert im

00:48.360 --> 00:49.040
Konstruktor.

00:49.640 --> 00:52.080
Und am Ende werden noch die Buchstaben A, I und N hinzugefügt.

00:52.700 --> 00:53.940
Und dann wird das Ganze ausgegeben.

00:54.820 --> 00:57.400
Und die Frage ist natürlich wie immer, was passiert?

00:58.840 --> 01:00.420
Es gibt so ein paar Möglichkeiten.

01:01.140 --> 01:02.460
Wir haben hier eine Zufallszahl.

01:02.460 --> 01:06.200
Das heißt, wir wissen nicht genau, in welchem Case oder ob wir im

01:06.200 --> 01:07.480
Default Case landen.

01:09.300 --> 01:12.060
Und dann bleibt eben die Frage, was passiert da?

01:13.940 --> 01:15.980
Am Anfang ist der Stringbuffer noch null.

01:16.740 --> 01:17.540
Das ist aber kein Problem.

01:17.640 --> 01:19.080
Der wird auf jeden Fall initialisiert.

01:19.920 --> 01:22.100
Sollte also zumindest mal keinen Laufzeitfehler geben.

01:22.760 --> 01:23.120
Hoffe ich.

01:24.040 --> 01:26.560
Die Alternativen, die ich Ihnen anbieten kann, sind die folgenden.

01:27.240 --> 01:29.660
Wir bekommen ein Wort aus Pain, Gain oder Main.

01:29.660 --> 01:33.780
Das entspricht genau diesen drei Fällen, die diese Fallunterscheidung

01:33.780 --> 01:33.980
hat.

01:35.320 --> 01:37.720
Oder es kommt immer das Wort Main raus.

01:39.020 --> 01:40.360
Warum könnte das der Fall sein?

01:41.500 --> 01:45.760
Dann noch die Standardantworten, Übersetzerfehler und Laufzeitfehler.

01:47.100 --> 01:51.240
Und als Zusatzoption gibt es heute ganz frisch noch die E mit etwas

01:51.240 --> 01:51.720
anderes.

01:53.800 --> 01:56.480
Wer ist denn für einen Übersetzer oder einen Laufzeitfehler?

01:58.420 --> 01:59.540
Entweder oder ist egal.

01:59.700 --> 02:00.160
Eins für beide.

02:00.280 --> 02:02.660
C oder D, Übersetzerfehler oder Laufzeitfehler.

02:04.580 --> 02:06.800
Da sehe ich nur zwei einsame Händchen.

02:08.480 --> 02:12.520
Wer glaubt denn, dass zufällig ein Wort aus der Menge Pain, Gain oder

02:12.520 --> 02:13.260
Main rauskommt?

02:13.440 --> 02:14.700
Also Antwort A richtig ist.

02:17.480 --> 02:19.640
Sie müssen sich ein bisschen deutlicher melden.

02:19.760 --> 02:21.000
Ich sehe im Moment nur zwei Hände.

02:22.900 --> 02:24.600
Drei, vier, fünf.

02:26.480 --> 02:26.860
Okay.

02:27.520 --> 02:29.440
Wer glaubt, da kommt immer das Wort Main raus?

02:31.440 --> 02:33.300
Das ist bis jetzt die absolute Mehrheit.

02:34.120 --> 02:35.900
Und wer glaubt, es kommt was anderes raus?

02:37.980 --> 02:40.400
Drei, vier, fünf, sieben.

02:41.000 --> 02:41.320
Okay.

02:42.720 --> 02:48.180
Also die große Mehrheit, die sich gemeldet hat mit da kommt immer Main

02:48.180 --> 02:48.460
raus.

02:49.080 --> 02:50.060
Die haben leider nicht recht.

02:51.440 --> 02:51.900
Tut mir leid.

02:52.920 --> 02:54.220
Es kommt was anderes raus.

02:55.040 --> 02:56.200
Nichts von dem, was da steht.

02:56.360 --> 02:57.320
Es kommt was anderes raus.

02:58.160 --> 02:58.700
Und zwar Ain.

02:59.700 --> 03:00.280
A, I, N.

03:00.520 --> 03:01.020
Jedes Mal.

03:02.300 --> 03:03.440
Jetzt ist die Frage warum.

03:04.000 --> 03:05.880
Es haben sich ein paar gemeldet für etwas anderes.

03:06.160 --> 03:10.260
Ich hoffe, dass wenigstens bei einem von denen das eine Option war.

03:11.300 --> 03:13.360
Wer hat sich denn schon gedacht, dass da Ain rauskommt?

03:15.680 --> 03:18.600
Okay, wer kann sich jetzt erklären, warum da immer Ain rauskommt?

03:19.840 --> 03:20.500
Auch niemand.

03:22.180 --> 03:25.340
Naja, dieses Programmchen, das hat ein paar Probleme, die man

03:25.340 --> 03:26.660
vielleicht nicht auf den ersten Blick sieht.

03:26.760 --> 03:28.640
Aber wir gehen einfach mal von oben nach unten durch.

03:29.500 --> 03:33.940
Und das Erste, was hier falsch gemacht wird, das ist die Zufallszahl.

03:34.840 --> 03:38.140
Wenn Sie auf Random Next Int aufrufen und geben dann Parameter rein

03:38.140 --> 03:42.160
als Argument, dann bekommen Sie eine Zufallszahl aus dem Intervall 0.

03:43.380 --> 03:45.080
Exklusive dem, was Sie da angegeben haben.

03:45.180 --> 03:49.940
Das heißt, die 2, der zweite Case hier, der wird nie erreicht.

03:50.520 --> 03:51.920
Das geht einfach nicht.

03:53.100 --> 03:54.520
Das ist schade.

03:55.120 --> 03:57.640
Das heißt, Gain, das treffen wir schon mal nie.

03:58.880 --> 04:00.340
Dann gibt es noch ein anderes Problem.

04:00.940 --> 04:02.940
Das hat auch was mit dieser Fallunterscheidung zu tun.

04:03.580 --> 04:05.100
Und was Sie hier sehen, ist ein Switch Case.

04:06.020 --> 04:08.980
Und wann immer Sie ein Switch Case programmieren, machen Sie bitte

04:08.980 --> 04:09.620
Breaks hin.

04:11.280 --> 04:14.120
Breaks schreibt man eigentlich hinter den jeweiligen Fall.

04:14.380 --> 04:16.700
Und das heißt übrigens, hier ist dieser Fall fertig.

04:17.160 --> 04:18.940
Jetzt kommt der nächste, vielleicht ein anderer.

04:18.940 --> 04:23.500
Und wenn man dieses Break weglässt, dann läuft Java einfach weiter

04:23.500 --> 04:23.860
durch.

04:24.560 --> 04:27.880
Das heißt, selbst wenn hier oben bei dem Random Next Int eine 1

04:27.880 --> 04:33.380
rauskommt, dann wird hier zuerst Pain aufgerufen, mit P, dann mit G

04:33.380 --> 04:34.160
und dann mit M.

04:34.720 --> 04:36.920
Das heißt, das wäre eigentlich immer der Default Fall.

04:37.420 --> 04:39.820
Und dann wäre ja eigentlich Antwort B richtig.

04:41.340 --> 04:43.740
Aber da ist halt noch ein Problem drin in diesem Stück Code.

04:43.740 --> 04:47.840
Und das ist die Angabe hier von den Konstruktoren.

04:48.560 --> 04:51.000
Was Sie hier sehen, sind Charakter-Konstanten.

04:52.020 --> 04:53.060
Einfache Anführungszeichen.

04:53.340 --> 04:54.740
Das ist was anderes als ein String.

04:55.040 --> 04:57.220
Der hat zwei, also doppelte Anführungszeichen.

04:58.180 --> 05:01.740
Und der String-Buffer, der hat überhaupt keinen Konstruktor mit einem

05:01.740 --> 05:02.140
Charakter.

05:02.660 --> 05:05.520
Und das wird auch nicht nach String gecastet, sondern nach Int.

05:07.000 --> 05:11.640
Und dieser Int, der da reinkommt, der sagt, wie groß der String-Buffer

05:11.640 --> 05:12.680
sein soll am Anfang.

05:13.500 --> 05:17.320
Und der Cast von einem Buchstaben auf eine Zahl, das geht einfach über

05:17.320 --> 05:18.820
die Ascii-Tabelle.

05:19.700 --> 05:22.720
Und dann hat man mit M eben einen String-Buffer der Größe 77.

05:23.980 --> 05:26.980
Und da füllt man dann hinterher AI und N rein.

05:27.540 --> 05:28.800
Dann kommt halt immer N raus.

05:29.020 --> 05:31.560
Völlig egal, was in dieser Fallunterscheidung eigentlich passiert

05:31.560 --> 05:32.740
hätte sollen.

05:33.860 --> 05:34.440
Oder so ähnlich.

05:35.560 --> 05:38.340
Was Sie da vielleicht daraus lernen sollten, ist, dass man

05:38.340 --> 05:43.300
Zufallszahlen korrekt sich ziehen lässt.

05:43.860 --> 05:46.320
Das heißt, die Zahl, die man da angibt, die wird man nie sehen.

05:47.980 --> 05:49.320
Bisschen intuitiv vielleicht.

05:50.440 --> 05:53.980
Das nächste ist, wenn Sie eine Fallunterscheidung machen, dann bitte

05:53.980 --> 05:55.400
immer Breaks hintendran schreiben.

05:55.500 --> 05:57.860
Hinter jedem Fall, auch hinter dem Default-Case.

05:59.060 --> 06:02.160
Es ist zwar in der Regel so, dass Default ganz unten steht.

06:02.160 --> 06:05.620
Jetzt gehen wir alle Fälle durch und wenn keiner passt, dann nehmen

06:05.620 --> 06:06.260
wir halt Default.

06:06.760 --> 06:09.120
Aber man kann Default auch in die erste Zeile schreiben.

06:09.940 --> 06:11.080
Und die Case ist drunter weg.

06:11.760 --> 06:12.580
Oder man kann es mischen.

06:13.220 --> 06:15.020
Das heißt, da gibt es keine Ordnung in dem Sinne.

06:15.180 --> 06:17.500
Schreiben Sie am besten hinter jedem Fall einen Break.

06:17.820 --> 06:20.540
Und wenn da kein Break hin soll, dann schreiben Sie einen Kommentar

06:20.540 --> 06:20.800
hin.

06:21.280 --> 06:22.720
Damit Ihr Kollege keinen hin macht.

06:24.520 --> 06:25.720
Also da immer aufpassen.

06:25.720 --> 06:32.060
Und dann sollten Sie sich darum bemühen, herauszufinden, ob die API,

06:32.200 --> 06:35.440
die Sie da benutzen, tatsächlich auch so benutzt werden kann.

06:35.940 --> 06:39.440
Nur weil Java Ihnen da automatisch einen Cast einflechtet, heißt das

06:39.440 --> 06:41.900
noch lange nicht, dass Sie das bekommen, was Sie eigentlich haben

06:41.900 --> 06:42.160
wollten.

06:42.740 --> 06:45.040
Gerade hier sieht man, dass das auch mal daneben gehen kann.

06:47.740 --> 06:49.240
Der letzte Punkt hier unten.

06:49.700 --> 06:52.020
Bei Unsicherheiten in der Dokumentation nachschauen.

06:52.440 --> 06:53.480
Das gilt fast immer.

06:53.480 --> 06:57.580
Bei Java, bei der Standardbibliothek, da kommt man manchmal so in

06:57.580 --> 06:58.060
Versuchungen.

06:58.140 --> 07:01.080
Man schreibt es halt hin und wenn in Eclipse kein Fehler kommt, dann

07:01.080 --> 07:01.630
wird es schon stimmen.

07:02.780 --> 07:04.040
Das ist nicht immer richtig.

07:04.480 --> 07:07.020
Also gucken Sie nach, was die Methoden tun sollen, die Sie da

07:07.020 --> 07:07.500
aufrufen.

07:07.660 --> 07:11.340
Und insbesondere bei Konstruktoren überlegen Sie sich vorher, was Sie

07:11.340 --> 07:11.840
haben wollen.

07:11.920 --> 07:13.880
Und dann lesen Sie nach, ob das tatsächlich passiert.

07:16.040 --> 07:17.160
Ein Punkt steht hier noch.

07:17.280 --> 07:18.900
Doppelte und einfache Anführungszeichen.

07:19.040 --> 07:20.080
Wohl überlegt einsetzen.

07:20.080 --> 07:23.840
Das ist ein bisschen platt, weil eigentlich heißt das, wenn man es

07:23.840 --> 07:26.920
richtig formuliert, schauen Sie sich mal an, was für einen Datentyp

07:26.920 --> 07:27.920
Sie da hingeschrieben haben.

07:28.800 --> 07:32.480
Ein Character oder ein String oder vielleicht ein Int, wo ein Double

07:32.480 --> 07:33.060
hingehört.

07:33.720 --> 07:37.420
Oder Sie weisen irgendwas einem Double-Wert zu, rechnen aber

07:37.420 --> 07:38.700
tatsächlich mit Ganzzahlen.

07:39.300 --> 07:41.600
Das heißt, bei der Berechnung wird abgeschnitten, obwohl Sie das

07:41.600 --> 07:43.660
eigentlich mit Gleitkommazahlen speichern könnten.

07:44.240 --> 07:46.100
Passen Sie auf, was für Datentypen Sie benutzen.

07:46.980 --> 07:49.460
Ich nehme an, es hat keiner eine Frage zu diesem Puzzler.

07:49.560 --> 07:53.540
Deswegen bringe ich gleich weiter in den Vorlesungstext.

07:54.700 --> 07:58.640
Wir haben uns letztes Mal beschäftigt mit der linguistischen Analyse.

07:59.400 --> 08:01.600
Und da waren wir fast durchgekommen durch das Kapitel.

08:03.180 --> 08:08.260
Ich zeige gerade noch mal die letzten zwei Inhaltsfolien.

08:11.800 --> 08:15.720
Das war diese hier mit dem Whois-Server-Beispiel.

08:16.520 --> 08:19.080
Und wir hatten uns überlegt, wenn man sich die Semantik von einem

08:19.080 --> 08:23.220
Textdokument anschaut und überlegt, dann kann man die explizit

08:23.220 --> 08:26.460
hinschreiben, in diesem Fall hier mit thematischen Rollen.

08:26.680 --> 08:29.900
Sie erinnern sich, es gab sowas wie ein Agents, es gab ein Patients,

08:30.040 --> 08:33.240
es gab ein Actus für tatsächliche Aktionen.

08:34.400 --> 08:36.800
Wenn man das explizit hinschreibt, dann gibt es keinen

08:36.800 --> 08:38.180
Interpretationsspielraum mehr.

08:38.840 --> 08:41.960
Das ist das eine, was da vorteilhaft ist.

08:42.040 --> 08:44.860
Das andere ist, wenn Sie das genau so machen, dann können Sie aus

08:44.860 --> 08:47.700
diesem Ergebnis hier automatisch ein Klassendiagramm ableiten.

08:47.940 --> 08:51.520
Das für die Whois-Spezifikation, die hat noch zwei, drei Sätze mehr.

08:52.080 --> 08:53.740
Das sieht dann so aus, dass da rauskommt.

08:54.600 --> 08:55.720
Das hatte ich Ihnen schon gezeigt.

08:55.820 --> 08:58.300
Wir sind einmal durchgegangen und haben festgestellt, es gibt einen

08:58.300 --> 08:59.860
Server und der hört auf einem Port.

08:59.860 --> 09:01.920
Und den gibt es auch als Klasse.

09:02.140 --> 09:03.020
Und es gibt einen Client.

09:03.400 --> 09:05.320
Und einmal ist der Client jemand, der was gibt.

09:05.580 --> 09:07.480
Donor, nämlich diese Requests.

09:08.360 --> 09:10.420
Und der Server ist derjenige, der es empfängt.

09:10.640 --> 09:13.720
Und auf der unteren Hälfte sieht man, dass der Client ein Empfänger

09:13.720 --> 09:14.740
ist, ein Rezipient.

09:15.160 --> 09:17.200
Und zwar von einer Antwort, von einer Response.

09:18.500 --> 09:19.960
Schauen Sie sich das nochmal an.

09:21.200 --> 09:23.940
Insbesondere, wenn Sie das nächste Übungsblatt bearbeiten und wenn Sie

09:23.940 --> 09:27.140
vielleicht sich auf die Klausur vorbereiten.

09:27.140 --> 09:30.000
Es kann schon gut sein, dass Sie ein paar Sätze bekommen, an die Sie

09:30.000 --> 09:31.640
thematische Rollen dranschreiben müssen.

09:32.300 --> 09:37.300
Und oder aus so einem annotierten Text ein Diagramm bauen müssen.

09:37.880 --> 09:40.600
Und wenn Sie so ein Diagramm bauen müssen, dann blätter ich mal

09:40.600 --> 09:41.960
nochmal ein paar Folien zurück.

09:42.880 --> 09:44.680
Sie erinnern sich an diese Übersetzungstabellen.

09:46.700 --> 09:51.940
Wenn Sie einen annotierten Satz haben und Sie kennen die Regel, die

09:51.940 --> 09:53.460
wir hier in der Vorlesung besprochen haben.

09:53.460 --> 09:58.440
Zum Beispiel aus einem Omnium und einem Path steht hier, wenn Sie

09:58.440 --> 10:00.780
gemeinsam auftreten, eine Komposition.

10:01.500 --> 10:03.560
Keine Aggregation, sondern eine Komposition.

10:04.100 --> 10:05.380
Dann malen Sie das genau so hin.

10:06.660 --> 10:10.140
Nicht so hinmalen, wie Sie es modellieren würden, sondern malen Sie es

10:10.140 --> 10:12.780
genau so hin, wie es die Tabelle vorgibt.

10:13.920 --> 10:16.740
Sie sollen nicht modellieren, was Sie alles im Kopf haben und was Sie

10:16.740 --> 10:20.720
über Puzzleteile wissen, sondern Sie sollen das hinmalen, was in der

10:20.720 --> 10:21.740
Spezifikation steht.

10:21.740 --> 10:26.140
In der Regel sind die Aufgaben genau so, dass Sie exakt am Text ein

10:26.140 --> 10:29.460
Diagramm bauen sollen und nicht noch Zusatzwissen mit einfließen

10:29.460 --> 10:29.700
lassen.

10:30.220 --> 10:33.280
Das ist ein bisschen künstlich, weil in der Realität ist das genau

10:33.280 --> 10:34.820
das, was nicht passieren soll.

10:34.940 --> 10:37.840
Da müssen Sie über den Tellerrand hinausschauen und müssen

10:37.840 --> 10:40.920
gegebenenfalls nachfragen bei demjenigen, der die Spezifikation

10:40.920 --> 10:41.540
geschrieben hat.

10:41.860 --> 10:44.740
Wenn Sie hier jetzt Interpretationsspielraum haben, dann müssen Sie

10:44.740 --> 10:47.600
abklären, ob Sie die richtige Interpretation gewählt haben oder eben

10:47.600 --> 10:48.100
die falsche.

10:48.100 --> 10:52.740
Wenn Sie Interesse haben an linguistischen Dingen in der

10:52.740 --> 10:57.020
Softwaretechnik, dann können Sie im Master nochmal bei unserem

10:57.020 --> 10:58.020
Lehrstuhl vorbeikommen.

10:58.900 --> 11:01.480
Wir haben da einige interessante Dinge.

11:01.600 --> 11:04.720
Wir haben eine Vorlesung Sprachverarbeitung in der Softwaretechnik, wo

11:04.720 --> 11:08.300
Sie lernen, wie man Sprachverarbeitungswerkzeuge von den

11:08.300 --> 11:11.780
Computerlinguisten einsetzen kann im Softwareentwicklungsprozess.

11:12.340 --> 11:15.560
Und zwar nicht als Baustein von der Software, die Sie entwerfen,

11:15.560 --> 11:19.180
sondern als Hilfsmittel für den Informatiker, der sich damit

11:19.180 --> 11:19.880
beschäftigen muss.

11:20.480 --> 11:23.880
Da gibt es zum Beispiel so Dinge wie automatisieren von

11:23.880 --> 11:24.780
Entwurfsaufgaben.

11:25.080 --> 11:26.740
Das ist genau das, was wir gerade gesehen haben.

11:26.960 --> 11:30.000
Ausgehend von einem annotierten Text automatisierten Diagrammen

11:30.000 --> 11:34.260
erzeugen oder Ablaufpläne erzeugen oder Unit-Tests erzeugen.

11:35.940 --> 11:38.560
Was wir auch machen, ist Qualitätssicherung für Anforderungsdokumente.

11:39.380 --> 11:43.140
Stellen Sie sich vor, Sie schreiben in ein Anforderungsdokument

11:46.080 --> 11:49.400
nachdem die Bücher zurückgegeben wurden, wenn Sie sich in der

11:49.400 --> 11:50.330
Bibliothek befinden.

11:51.320 --> 11:54.020
Nachdem die Bücher zurückgegeben wurden, passiert irgendwas.

11:55.120 --> 11:57.820
Dann fehlt in diesem Satz, naja, wer gibt es denn zurück?

11:58.240 --> 11:58.700
Und an wen?

11:59.480 --> 12:00.160
Und vielleicht wann?

12:00.320 --> 12:00.680
Und wo?

12:01.660 --> 12:06.320
Wenn Sie solche offenen Punkte haben in der Spezifikation, dann kann

12:06.320 --> 12:09.280
derjenige, der sie implementiert, im Prinzip relativ frei entscheiden,

12:09.380 --> 12:10.260
was er da eigentlich macht.

12:10.780 --> 12:13.800
Vielleicht macht er das unbewusst, aber irgendeine Entscheidung wird

12:13.800 --> 12:16.720
er treffen und vielleicht ist es nicht die, die Sie ursprünglich im

12:16.720 --> 12:17.160
Kopf hatten.

12:17.720 --> 12:21.500
Und Sie können mit Software-Unterstützung solche Probleme finden.

12:21.820 --> 12:23.900
In der Vorlesung erklären wir Ihnen, wie das funktioniert.

12:25.060 --> 12:27.640
Was wir auch machen, ist ein Seminar, ein Praktikum.

12:29.160 --> 12:31.120
Da wird ein Lego-Roboter programmiert.

12:31.960 --> 12:34.980
Lego-Roboter-Programmierung gibt es in der Uni an drei, vier Stellen.

12:35.640 --> 12:38.460
In der Regel wird da Java-Code geschrieben, weil das das ist, was auf

12:38.460 --> 12:39.300
der Maschine läuft.

12:39.300 --> 12:42.840
Oder wenn Sie an der Kinder-Uni sind, dann dürfen Sie das Lego

12:42.840 --> 12:44.240
-Entwicklungs -Framework benutzen.

12:45.660 --> 12:49.420
Aber bei uns im Praktikum werden Sie eine Software-Kette selbst bauen,

12:50.000 --> 12:52.700
die dazu führt, dass man diesen Roboter hinterher mit englischen

12:52.700 --> 12:53.780
Sätzen programmieren kann.

12:54.580 --> 12:57.560
Das heißt, Sie schreiben gar keine Programmiersprache mehr hin,

12:57.600 --> 12:58.500
sondern englischen Text.

12:59.100 --> 13:01.440
Und das, was Sie in dem Praktikum machen, das sorgt dafür, dass dieser

13:01.440 --> 13:03.100
Text übersetzt wird in Java-Code.

13:03.880 --> 13:06.600
Wenn Sie das interessiert, dann kommen Sie bei uns vorbei.

13:06.600 --> 13:09.000
Wenn nicht, dann erzählen Sie anderen Leuten, die es vielleicht

13:09.000 --> 13:09.540
interessiert.

13:10.480 --> 13:11.540
Dann kann man ein bisschen Spaß haben.

13:14.100 --> 13:18.660
Haben Sie noch Fragen zu dem Definitionskapitel im Allgemeinen?

13:19.040 --> 13:21.480
Also die letzten anderthalb, zwei Vorlesungen.

13:23.540 --> 13:25.240
Hätten Sie jetzt die Chance, die zu stellen.

13:26.120 --> 13:27.860
Ansonsten fangen wir an mit dem Entwurf.

13:33.040 --> 13:37.240
In der Entwurfsphase sind wir jetzt schon in der dritten Stufe vom

13:37.240 --> 13:37.700
Wasserfall.

13:37.700 --> 13:40.880
Das heißt, die Planung ist durch und die Definition ist durch.

13:41.020 --> 13:43.920
Wir haben schon das eine oder andere Klassenmodell.

13:44.000 --> 13:45.320
Wir haben vielleicht Sequenzdiagramme.

13:45.420 --> 13:46.720
Wir haben auf jeden Fall Use Cases.

13:47.500 --> 13:50.180
Was wir aber nicht haben, ist ein wirkliches Software-System.

13:50.880 --> 13:52.800
Wir haben uns im Prinzip nur Fragmente angeschaut.

13:53.460 --> 13:56.800
Und ob das Ganze performant ist, was wir da gemacht haben, steht auf

13:56.800 --> 13:57.660
einer ganz anderen Karte.

13:58.740 --> 14:02.500
Und im Entwurf müssen wir uns damit auseinandersetzen, dass dieses

14:02.500 --> 14:06.000
Software -System, das wir bauen, in sich schlüssig wird und in sich

14:06.000 --> 14:08.800
rund wird und schön wartbar ist und so weiter.

14:09.660 --> 14:12.320
Das heißt, wir machen hier jetzt verschiedene Unterkapitel durch,

14:12.460 --> 14:13.200
einen kleinen Überblick.

14:13.440 --> 14:15.920
Dann gucken wir uns an, wie ein modularer Entwurf funktioniert.

14:16.480 --> 14:20.220
Das ist ein bisschen, ich sag mal, 1970er-Jahre.

14:21.600 --> 14:24.300
Werden Sie aber unter Umständen wieder treffen, wenn Sie irgendwo ein

14:24.300 --> 14:27.220
Legacy -System betreuen, pflegen, weiterentwickeln müssen.

14:27.980 --> 14:29.980
Danach geht es zum objektorientierten Entwurf.

14:29.980 --> 14:32.200
Das baut im Prinzip darauf auf.

14:32.480 --> 14:34.980
Allerdings gibt es in der Objektorientierung ein paar Dinge, die wir

14:34.980 --> 14:36.580
ausnutzen können beim Entwerfen.

14:36.980 --> 14:37.940
Das wollen wir natürlich tun.

14:38.900 --> 14:42.140
Und dann werden wir uns Architekturmuster und Entwurfsmuster

14:42.140 --> 14:42.620
anschauen.

14:42.940 --> 14:45.320
Das heißt, Architekturmuster, das sind ganz große Muster.

14:45.500 --> 14:47.920
Wie strukturiere ich eine Anwendung global?

14:48.900 --> 14:53.500
Und Entwurfsmuster, das sind Lösungen für kleine Spezialprobleme, aber

14:53.500 --> 14:55.200
eben Probleme, die häufig auftreten.

14:55.200 --> 14:59.740
Und deswegen lohnt es sich, diese Entwurfsmuster zu kennen und auch

14:59.740 --> 15:02.020
erklären zu können, wenn man mit einem Kollegen darüber spricht.

15:02.220 --> 15:05.700
Oder wenn man das einem Auftragnehmer erklären will, kann man einfach

15:05.700 --> 15:08.740
sagen, hier, nimm doch das Entwurfsmuster Brücke oder Bridge.

15:09.760 --> 15:10.860
Wissen die genau, was sie bauen müssen?

15:11.080 --> 15:14.520
Und sie erklären nicht umständlich mit drei Vererbungshierarchien und

15:14.520 --> 15:16.220
den Relationen, was sie eigentlich meinen.

15:17.040 --> 15:21.060
Das heißt, da bekommen sie ein Vokabular in die Hand, wo sie sich mit

15:21.060 --> 15:26.320
anderen ausgebildeten Informatikern unterhalten können.

15:27.620 --> 15:31.220
Aber, wie gesagt, am Anfang steht die Einführung unter Überblick.

15:31.940 --> 15:36.280
Die Aufgabe des Entwerfens ist, aus den Anforderungen und allem, was

15:36.280 --> 15:40.160
aus der Definitionsphase rauskam, eben eine Softwarearchitektur zu

15:40.160 --> 15:43.540
entwickeln, die am besten alle Anforderungen erfüllt.

15:43.540 --> 15:45.160
Das wäre ja ganz praktisch.

15:46.640 --> 15:50.760
Und deswegen muss man sich jetzt nicht mehr überlegen, was bauen wir

15:50.760 --> 15:51.140
eigentlich.

15:51.640 --> 15:53.660
Das ist ja in der Definitionsphase schon passiert.

15:54.020 --> 15:56.180
Sondern jetzt geht es darum, wie strukturieren wir das Ganze.

15:57.300 --> 16:00.540
Vielleicht sogar unter Berücksichtigung von anderen Nebenbedingungen.

16:01.900 --> 16:02.460
Randbedingungen.

16:03.740 --> 16:06.380
Die Softwarearchitektur ist damit eine Gliederung von dem

16:06.380 --> 16:08.980
Softwaresystem in Komponenten oder Subsysteme.

16:08.980 --> 16:12.180
Und die können natürlich aus Modulen bestehen oder aus Klassen.

16:12.280 --> 16:15.920
Je nachdem, ob wir uns im objektorientierten Entwurf befinden oder im

16:15.920 --> 16:16.780
modularen Entwurf.

16:17.700 --> 16:20.700
Und Pakete und Bibliotheken, das sind natürlich die Subsysteme.

16:20.800 --> 16:22.900
Pakete kennen Sie aus dem objektorientierten Umfeld.

16:23.640 --> 16:26.020
Subsysteme würden Sie wahrscheinlich bauen, wenn Sie modular unterwegs

16:26.020 --> 16:26.320
sind.

16:27.680 --> 16:31.400
Was Sie herstellen müssen, ist eine Benutzrelation.

16:31.580 --> 16:33.960
Sie müssen sich überlegen, was sind denn die Komponenten, die ich in

16:33.960 --> 16:35.040
meiner Architektur habe.

16:35.040 --> 16:38.780
Und welche Komponente braucht welche anderen.

16:39.880 --> 16:44.060
Und im Idealfall gibt es eben nur Abhängigkeiten in eine Richtung.

16:44.280 --> 16:48.080
Wenn Sie sowas haben wie zwei Komponenten und A hängt von B ab und B

16:48.080 --> 16:51.300
hängt von A ab, dann können Sie die beiden nicht getrennt voneinander

16:51.300 --> 16:51.740
entwickeln.

16:52.020 --> 16:53.280
Das ist echt unschön.

16:54.080 --> 16:57.540
Sie wollen immer eine Architektur herstellen, wo Sie keine zyklischen

16:57.540 --> 16:58.540
Abhängigkeiten bekommen.

16:59.820 --> 17:02.140
Was dann optional noch dazu kommt, ist ein Feinentwurf.

17:02.140 --> 17:06.300
Das heißt, da geben Sie als Entwerfer, als Designer tatsächlich dem

17:06.300 --> 17:10.720
Implementierer vor, wie er die Datenstrukturen zu bauen hat oder wie

17:10.720 --> 17:12.480
er die Algorithmen auszuprogrammieren hat.

17:12.800 --> 17:15.160
Das heißt, da sehen Sie dann zum ersten Mal Pseudocode oder

17:15.160 --> 17:18.080
Datenstrukturen noch in der Modellierung drin.

17:18.680 --> 17:21.600
Und wenn Sie sich in einem verteilten System bewegen, dann müssen Sie

17:21.600 --> 17:25.180
natürlich auch sagen, auf welchem System Teil, auf welcher Maschine

17:25.180 --> 17:26.500
läuft welche Komponente.

17:27.380 --> 17:32.460
Wenn Sie sagen, ich habe hier ein Cluster aus 523 Knoten und nicht auf

17:32.460 --> 17:35.400
jeden Knoten kommt dasselbe, dann müssen Sie denjenigen, die das Zeug

17:35.400 --> 17:38.020
ausrollen, mal erklären, was Sie sich dabei gedacht haben bei der

17:38.020 --> 17:39.220
Strukturierung.

17:39.320 --> 17:40.360
Das alles passiert hier.

17:42.380 --> 17:46.760
Das heißt, aus dem Pflichtenheft, aus der Benutzungsoberfläche, die

17:46.760 --> 17:49.840
Sie bauen sollen und aus dem Handbuch und dem Hilfe-Konzept und alles,

17:50.100 --> 17:54.520
was eben in der Definitionsphase vorher schon entstanden ist, bauen

17:54.520 --> 17:55.880
Sie jetzt eine Software-Architektur.

17:56.300 --> 17:59.040
Und das ist ein Prozess, das ist nicht eine Übersetzung, die Sie

17:59.040 --> 18:02.520
instantan einfach hinkriegen, weil sie sind besonders gut, sondern es

18:02.520 --> 18:04.220
sind viele Schritte, die man da durchführen muss.

18:06.100 --> 18:08.780
Und vorher müssen Sie sich noch ein bisschen die Randbedingungen

18:08.780 --> 18:09.200
anschauen.

18:09.760 --> 18:11.140
Es könnte ja sein, dass es welche gibt.

18:11.200 --> 18:13.940
Zum Beispiel, es gibt Komponenten, die können Sie kaufen.

18:14.600 --> 18:16.440
Das sollten Sie dann höchstwahrscheinlich auch tun, weil

18:16.440 --> 18:19.720
Standardkomponenten in der Regel recht gut funktionieren.

18:19.920 --> 18:21.200
Warum das Rad neu erfinden?

18:21.960 --> 18:25.420
Aber wenn Sie so eine Standardkomponente bekommen, dann können Sie die

18:25.420 --> 18:27.840
natürlich nicht beliebig einbinden, sondern nur mit den

18:27.840 --> 18:29.000
Schnittstellen, die sie eben hat.

18:29.420 --> 18:32.160
Und das hat sicherlich Auswirkungen auf Ihren Entwurf.

18:32.460 --> 18:35.840
Sie können nicht in SAP überall reingreifen, wo Sie gerade wollen,

18:35.940 --> 18:38.780
sondern Sie können nur die Schnittstellen benutzen, die bereitgestellt

18:38.780 --> 18:39.080
werden.

18:40.380 --> 18:42.500
Es könnte sein, dass es Echtzeitbedingungen gibt.

18:42.740 --> 18:46.440
Das heißt, Sie müssen bestimmte Zeitanforderungen einhalten.

18:46.620 --> 18:49.300
Wie lange darf denn eine Anfrage brauchen, bis sie durchkommt?

18:50.020 --> 18:52.720
Und wenn Sie so eine Anforderung haben, müssen Sie sicherstellen, dass

18:52.720 --> 18:53.620
Sie die auch halten können.

18:54.380 --> 18:56.460
Sie müssen ja die Architektur so bauen, dass das klappt.

18:57.000 --> 18:59.740
Wenn Sie Sachen speichern müssen, müssen Sie mal kurz darüber

18:59.740 --> 19:00.300
nachdenken.

19:00.440 --> 19:03.900
Machen Sie das auf Papier, auf Disketten, falls Sie das noch kennen,

19:04.560 --> 19:07.460
auf Festplatten, auf Datenbanken, was auch immer.

19:07.800 --> 19:10.700
Auch das hat Auswirkungen auf die Architektur.

19:11.220 --> 19:13.980
Wenn Sie eine Datenbank benutzen, dann müssen Sie sich nicht allzu

19:13.980 --> 19:16.160
viel Gedanken darüber machen, wie das Zeug persistiert wird.

19:16.620 --> 19:18.300
Sie brauchen eine Schnittstelle zur Datenbank.

19:18.940 --> 19:21.400
Wenn Sie das alles selbst machen, dann müssen Sie sich über

19:21.400 --> 19:24.360
Konsistenz, Wiederherstellbarkeit und so weiter Gedanken machen.

19:24.360 --> 19:25.720
Und das müssen Sie auch vorsehen.

19:27.380 --> 19:30.460
Und dann kommt noch so ein bisschen Detailkram hinten dran.

19:30.740 --> 19:34.740
Wie wird das Ganze vom Ablauf her gesteuert?

19:35.160 --> 19:37.540
Gibt es ein großes Programm, das die ganzen Fäden zieht?

19:37.920 --> 19:41.740
Gibt es irgendwelche Ereignisse, die von außen eintreten und auf die

19:41.740 --> 19:42.480
Sie reagieren müssen?

19:43.420 --> 19:45.880
Läuft das Ganze sequenziell, läuft es parallel und so weiter?

19:46.520 --> 19:48.740
Und dann gibt es noch so Kleinkram.

19:49.020 --> 19:50.660
Wie wird das Ganze installiert?

19:51.100 --> 19:52.700
Wie wird es gestoppt?

19:52.860 --> 19:53.680
Wie wird es gestartet?

19:54.200 --> 19:56.360
Und wie werden die Zugriffsrechte vergeben und verwaltet?

19:57.060 --> 19:59.880
Das sind alles Dinge, die vermutlich nicht in den Anforderungen

19:59.880 --> 20:00.420
drinstehen.

20:01.100 --> 20:03.560
Da steht vielleicht drin, welche Berechtigungen es geben muss.

20:03.740 --> 20:06.740
Was darf ein Sachbearbeiter, was darf ein Kundensachbearbeiter tun?

20:07.420 --> 20:10.400
Aber wie das Ganze verwaltet wird und wie es vergeben wird und wie es

20:10.400 --> 20:13.180
durchgesetzt wird, das steht nicht in den Anforderungen.

20:13.180 --> 20:14.880
Das ist Ihre Aufgabe, das zu tun.

20:18.040 --> 20:21.420
Und dann gibt es noch eine Menge von nicht-funktionalen Anforderungen.

20:22.020 --> 20:24.180
Sie haben so etwas wie niedrige Kosten.

20:24.760 --> 20:27.060
Das ist offensichtlich etwas, was der Auftraggeber haben will.

20:28.480 --> 20:30.380
Er will aber auch eine rasche Entwicklung haben.

20:31.620 --> 20:33.400
Das heißt, wahrscheinlich braucht er viele Leute.

20:34.240 --> 20:36.540
Es gibt so Dinge wie saubere Schnittstellen.

20:37.460 --> 20:39.560
Das ist offensichtlich wichtig für den Entwickler.

20:39.560 --> 20:42.040
Der will sich nicht rumschlagen müssen mit schlecht definierten

20:42.040 --> 20:42.580
Schnittstellen.

20:43.140 --> 20:46.640
Und auch mit schlecht dokumentierten Schnittstellen wollen sie nicht

20:46.640 --> 20:47.060
arbeiten.

20:48.180 --> 20:52.100
Aber natürlich gute Dokumentation kostet Zeit und damit Geld.

20:52.540 --> 20:55.160
Das heißt, das ist etwas, was der Auftraggeber vielleicht gar nicht so

20:55.160 --> 20:55.540
haben will.

20:56.700 --> 20:58.920
Oder das interessiert ihn nicht, sagen wir es mal so.

20:59.540 --> 21:02.960
Und dann gibt es noch den Endbenutzer, dem ist auch völlig egal, wie

21:02.960 --> 21:03.800
die Schnittstellen sind.

21:03.940 --> 21:07.000
Ob die sauber sind oder weniger sauber, ob die dokumentiert sind oder

21:07.000 --> 21:07.220
nicht.

21:07.220 --> 21:10.460
Hauptsache, die Software funktioniert, ist einfach bedienbar.

21:10.600 --> 21:11.860
Das heißt, dem geht es um Ergonomie.

21:13.340 --> 21:15.260
Interessiert den Entwickler wahrscheinlich nicht so sehr.

21:16.080 --> 21:18.040
Und ob es den Auftraggeber interessiert?

21:18.600 --> 21:22.920
Naja, er will eigentlich nur, dass seine Leute mit der neuen Software

21:22.920 --> 21:23.800
gut arbeiten können.

21:23.960 --> 21:25.180
Also schneller sind als vorher.

21:26.620 --> 21:30.220
Wenn der Entwickler sagt, eine Textkonsole ist das Nonplusultra.

21:30.560 --> 21:35.320
Sie müssen nur 322 Tastaturkürzel auswendig lernen, dann ist alles

21:35.320 --> 21:35.620
gut.

21:35.620 --> 21:38.160
Dann sagt der Auftraggeber vielleicht, das ist cool.

21:39.200 --> 21:41.520
Zu meiner Zeit musste ich 1000 lernen, das ist total super.

21:42.240 --> 21:44.700
Aber die Endbenutzer, die wollen vielleicht eine GUI haben.

21:45.820 --> 21:47.660
Vielleicht wollen sie es auch auf dem Smartphone benutzen.

21:48.240 --> 21:51.600
Gleichzeitig zu einer echten Client-Anwendung.

21:51.980 --> 21:53.320
Alles das müssen sie sich überlegen.

21:54.140 --> 21:56.460
Und das Ganze müssen sie abwägen.

21:56.560 --> 21:58.100
Sie können nicht alles befriedigen.

21:58.780 --> 22:02.900
Sie können nicht in zwei Wochen mit einem Entwickler eine ergonomische

22:02.900 --> 22:05.620
Software liefern, die perfekt dokumentiert ist und alles macht.

22:05.980 --> 22:07.540
Es sei denn, die Software ist trivial.

22:08.800 --> 22:12.920
Der zentrale Punkt, das ist alles klar, Laufzeit versus Platzbedarf.

22:13.380 --> 22:16.200
Entweder sie rechnen alles immer aus, wenn es gebraucht wird, oder sie

22:16.200 --> 22:17.400
speichern alles immer ab.

22:17.480 --> 22:19.240
Dann müssen sie es nur noch holen.

22:19.580 --> 22:22.680
Wenn Speicherplatz teuer ist, dann wollen sie es ausrechnen.

22:22.860 --> 22:24.720
Wenn es schnell gehen muss, wollen sie es abspeichern.

22:25.080 --> 22:26.400
Sie können nicht beides machen.

22:27.240 --> 22:27.680
Höchstwahrscheinlich.

22:28.460 --> 22:30.800
Aber unter all diesen Beispielen gibt es eigentlich nur einen Punkt,

22:30.840 --> 22:31.560
der wirklich gut ist.

22:31.560 --> 22:32.160
Und das ist der letzte.

22:32.560 --> 22:34.340
Good, fast, cheap, pick any two.

22:35.380 --> 22:37.120
Alles drei, das geht nicht.

22:38.120 --> 22:41.200
Egal, wo sie ziehen, irgendwo an einer anderen Stelle wird sich ihr

22:41.200 --> 22:42.040
Projekt bewegen.

22:42.640 --> 22:46.460
Sie können sagen, das ist mir aber viel, viel zu langsam, wie ihr

22:46.460 --> 22:46.900
entwickelt.

22:48.120 --> 22:49.940
Jetzt da mal noch fünf Entwicklerteams dazu.

22:50.380 --> 22:53.360
Können wir machen, dann wird es wahrscheinlich früher fertig, aber es

22:53.360 --> 22:54.160
wird ein bisschen teurer.

22:55.640 --> 22:57.520
Nämlich fünf Entwicklerteams mehr.

22:58.060 --> 22:59.020
Die muss ich ja bezahlen.

22:59.020 --> 23:01.960
Und ich muss sie wahrscheinlich auch noch administrieren und

23:01.960 --> 23:02.600
koordinieren.

23:03.460 --> 23:06.980
Das heißt, wenn ich eins habe und wenn ich sechs habe, bin ich nicht

23:06.980 --> 23:08.620
fünfmal schneller.

23:10.040 --> 23:11.120
Müssen sie also abwägen.

23:11.740 --> 23:15.200
Und erst, wenn das alles klar ist, wie sie das abwägen dürfen.

23:15.740 --> 23:18.100
Ihr Auftraggeber wird ihnen einfach sagen, was sie machen können.

23:18.340 --> 23:20.600
Sie können ihm vielleicht erklären, was gut ist, aber er wird es

23:20.600 --> 23:21.660
letztendlich entscheiden wollen.

23:22.300 --> 23:24.700
Erst wenn das alles klar ist, können sie die erste Architektur in

23:24.700 --> 23:26.160
Angriff nehmen und es tatsächlich bauen.

23:27.540 --> 23:31.440
Wie ich Ihnen gesagt habe, gibt es zwei grob unterschiedliche

23:31.440 --> 23:32.400
Entwurfsmethoden.

23:32.620 --> 23:35.100
Den modularen Entwurf und den objektorientierten Entwurf.

23:35.780 --> 23:39.220
Und was Sie sich von dieser Folie bitte merken ist, alles was im

23:39.220 --> 23:43.560
modularen Entwurf gilt, gilt im objektorientierten Entwurf immer noch.

23:44.400 --> 23:46.360
Es wird nur noch mehr dazukommen.

23:46.860 --> 23:49.660
Es gibt einfach Dinge im objektorientierten Entwurf, die es bei

23:49.660 --> 23:50.560
Modulen nicht gibt.

23:51.480 --> 23:54.420
Aber Sie dürfen nichts vergessen von dem, was im modularen Entwurf

23:54.420 --> 23:55.020
erklärt wird.

23:57.720 --> 24:00.800
Dazu sollten Sie im Balzard nachlesen, wenn Sie einen haben.

24:01.140 --> 24:03.300
Wenn nicht, gehen Sie mal in der Bibliothek vorbei und blättern das

24:03.300 --> 24:03.560
auf.

24:06.160 --> 24:09.660
Was kommt raus, wenn Sie den modularen Entwurf gemacht haben?

24:09.760 --> 24:11.020
Es kommt ein Modulführer raus.

24:12.280 --> 24:16.880
Das ist schlicht und ergreifend so etwas wie eine Detailspezifikation.

24:17.020 --> 24:18.760
Da steht eben drin, was für Module gibt es.

24:18.760 --> 24:19.480
Was können die?

24:19.620 --> 24:20.800
Was für Schnittstellen haben die?

24:22.520 --> 24:23.960
Eine komplette Beschreibung.

24:24.760 --> 24:27.780
Und Sie werden darin Entwurfsmuster wieder sehen.

24:27.900 --> 24:30.180
Zum Beispiel so etwas wie eine Schichtenarchitektur oder ein

24:30.180 --> 24:31.380
Fließband, eine Pipeline.

24:32.460 --> 24:33.840
Das alles brauchen Sie an der Stelle.

24:34.500 --> 24:37.820
Und was dann natürlich auch rausfällt, sind die Modul-Schnittstellen.

24:38.260 --> 24:42.880
Das heißt, da haben Sie Ein- und Ausgabe-Parameter und alles, was Sie

24:42.880 --> 24:44.600
brauchen, um so ein Modul anzusprechen.

24:45.200 --> 24:46.260
Das müssen Sie aufschreiben.

24:49.640 --> 24:51.260
Idealerweise machen Sie das formal.

24:52.980 --> 24:56.800
Idealerweise heißt, wenn Ihr Projekt wahnsinnig viel Geld hat oder Sie

24:56.800 --> 24:57.860
bei der NASA arbeiten.

24:58.800 --> 25:00.980
Ansonsten wird es höchstwahrscheinlich informell sein.

25:01.620 --> 25:03.140
Sprich, Sie schreiben das auf Englisch dahin.

25:03.820 --> 25:06.060
Vielleicht kriegen Sie es hin, an der einen oder anderen Stelle eine

25:06.060 --> 25:09.340
Grammatik anzugeben oder irgendwas mit XML für die Ein- und Ausgabe

25:09.340 --> 25:11.440
-Dateien, dass Sie da ein Style-Sheet anlegen oder so.

25:11.440 --> 25:15.440
Aber in der Regel wird das alles Englisch oder Deutsch sein, je

25:15.440 --> 25:16.380
nachdem, wo Sie arbeiten.

25:17.740 --> 25:19.880
Was dann auch dazu kommt, ist die Benutzt-Relation.

25:20.180 --> 25:22.580
Das waren die Abhängigkeiten zwischen den einzelnen Modulen.

25:23.200 --> 25:26.920
Und was Sie da eigentlich haben wollen, ist einen a-zyklischen

25:26.920 --> 25:27.820
gerichteten Graph.

25:28.860 --> 25:31.500
Das heißt, Sie haben eine Menge von Modulen, das sind die Knoten.

25:31.940 --> 25:34.580
Und die Benutzt-Relation, das sind die gerichteten Kanten dazwischen.

25:34.780 --> 25:36.400
Und Sie wollen da keine Zyklen drin haben.

25:36.960 --> 25:38.120
Hatte ich Ihnen vorhin schon gesagt.

25:38.120 --> 25:41.600
Wenn A von B abhängt und B hängt von A ab, dann müssen Sie beides

25:41.600 --> 25:43.240
gleichzeitig richtig und fertig haben.

25:43.740 --> 25:44.660
Dann wissen Sie nicht, ob es geht.

25:45.740 --> 25:47.400
Und bis dorthin haben Sie keine Ahnung.

25:48.200 --> 25:50.200
Deswegen a-zyklisch und gerichtet.

25:51.400 --> 25:52.600
Dann ist das Ganze gut.

25:52.880 --> 25:54.040
Und dann nennt man das Hierarchie.

25:55.180 --> 25:57.500
Steht bestimmt auf einer anderen Folie auch noch drauf.

25:58.600 --> 26:00.380
Optional kommt noch ein Feinentwurf dazu.

26:00.620 --> 26:05.220
Das war das mit Datenstrukturbeschreibung und möglicherweise

26:05.220 --> 26:06.320
Algorithmenbeschreibung.

26:06.320 --> 26:11.000
Wie gesagt, optional, weil das macht man tatsächlich nur dort, wo es

26:11.000 --> 26:13.160
wirklich um kleine Details geht.

26:13.400 --> 26:17.200
Wenn Sie beim Entwerfen der Architektur schon genau wissen, diese

26:17.200 --> 26:19.100
Datenstruktur muss es sein und keine andere.

26:19.280 --> 26:21.140
Sonst kann ich meine Anforderungen nicht halten.

26:21.940 --> 26:23.940
Dann sollten Sie das in den Feinentwurf reinschreiben.

26:24.320 --> 26:27.280
Wenn Sie sagen, mir ist es völlig egal, was für eine Datenstruktur er

26:27.280 --> 26:28.560
da benutzt, der Entwickler.

26:29.040 --> 26:30.660
Dann schreiben Sie es ihm auch nicht vor.

26:30.740 --> 26:32.440
Dann soll er die nehmen, die gerade am besten passt.

26:34.600 --> 26:36.320
Ja, Pseudocode kennen Sie schon.

26:36.780 --> 26:39.060
Schreibt man in der Regel in irgendeiner Hochsprache hin oder

26:39.060 --> 26:41.000
irgendwas, was so aussieht wie eine Hochsprache.

26:41.600 --> 26:44.680
Und zu sehen hier schon auf der Folie, wird in der

26:44.680 --> 26:47.440
Implementierungsphase von Hand in Assembler umgesetzt.

26:48.540 --> 26:50.120
Das passiert Ihnen hoffentlich nicht so oft.

26:52.660 --> 26:56.560
Aber, modularer Entwurf, Ende der 70er, da war das halt state of the

26:56.560 --> 26:56.760
art.

26:56.760 --> 27:00.200
Wenn Sie was haben wollten, was wirklich rennt, was sauschnell ist,

27:00.900 --> 27:03.680
dann müssen Sie es wirklich ganz unten auf Maschinenebene hin

27:03.680 --> 27:04.000
codieren.

27:05.260 --> 27:06.340
Hoffentlich trifft Sie das nicht.

27:06.480 --> 27:07.860
Es sei denn, Sie finden es total klasse.

27:08.020 --> 27:09.620
Dann wünsche ich Ihnen, dass es trifft.

27:10.860 --> 27:11.300
Je nachdem.

27:12.220 --> 27:14.960
Okay, es gibt zwei Sichtweisen.

27:15.120 --> 27:17.540
Das eine ist der externe, das andere der interne Entwurf.

27:19.540 --> 27:22.920
Extern ist im Prinzip das, was Sie brauchen, um so ein Modul zu

27:22.920 --> 27:23.340
benutzen.

27:23.340 --> 27:26.240
Das heißt, da wissen Sie, wie die Gesamtstruktur des Systems ungefähr

27:26.240 --> 27:26.860
aussehen soll.

27:27.000 --> 27:28.720
Und da kennen Sie die Ein- und Ausgabeschnittstellen.

27:29.660 --> 27:32.140
Aber den Feinentwurf, den brauchen Sie da eigentlich nicht.

27:33.080 --> 27:35.720
Sie müssen nicht wissen, wie Ihr Kollege das Modul konkret

27:35.720 --> 27:36.340
implementiert.

27:37.400 --> 27:39.420
Wahrscheinlich ist es sogar besser, wenn Sie es nicht wissen.

27:39.940 --> 27:42.140
Es reicht, wenn Sie die Schnittstellen haben.

27:47.160 --> 27:50.560
Das mit diesem a-zyklischen gerichteten Graph, das hängt einfach

27:50.560 --> 27:54.920
daran, dass Sie wollen, dass jedes Modul für sich genommen bearbeitet

27:54.920 --> 28:01.020
werden kann und dass es völlig ohne Kenntnis über Interna von anderen

28:01.020 --> 28:01.940
Module funktioniert.

28:02.680 --> 28:06.500
Das heißt, wenn Sie in einem Modul eine Datenstruktur haben, dann

28:06.500 --> 28:08.160
sollten Sie die nach außen hin verbergen.

28:08.440 --> 28:10.720
Sie sollten niemandem sagen, dass Sie mit einem Stack arbeiten.

28:10.720 --> 28:12.680
Es sei denn, das Modul ist ein Stack.

28:16.560 --> 28:18.620
Die Implementierungsdetails behalten Sie für sich.

28:19.380 --> 28:20.640
Die gehören nicht nach außen.

28:21.000 --> 28:24.280
Sie müssen da quasi eine Mauer hinziehen und durch die Mauer darf man

28:24.280 --> 28:25.200
nur die Schnittstellen sehen.

28:26.620 --> 28:29.520
Das ist deswegen wichtig, weil Sie sich nach außen hin abkapseln

28:29.520 --> 28:29.740
wollen.

28:30.400 --> 28:33.580
Stellen Sie sich vor, jemand weiß, wie die Interna Ihres Moduls

28:33.580 --> 28:37.100
funktionieren und sagt, hey cool, der hat da eine doppelt

28:37.100 --> 28:39.000
verschachtelte Indexstruktur im Hauptspeicher.

28:39.000 --> 28:41.900
Da greife ich mal rein, dann bin ich nämlich schneller.

28:42.880 --> 28:45.840
Und Sie überlegen sich dann irgendwann, dieser doppelt geschachtelte

28:45.840 --> 28:47.240
Index bringt es nicht.

28:48.300 --> 28:50.540
Sie machen einen dreifach geschachtelten raus oder Sie lassen den

28:50.540 --> 28:51.280
Index ganz weg.

28:52.460 --> 28:56.480
Dieses andere Modul, das da in Ihrem Index rumgefuhrwerkt hat, das hat

28:56.480 --> 28:58.600
dann ein Problem, das funktioniert nämlich nicht mehr.

28:59.680 --> 29:02.320
Und das heißt, wenn Sie eine Entscheidung ändern, dann muss jemand

29:02.320 --> 29:03.620
anders hinter Ihnen herräumen.

29:04.560 --> 29:05.780
Und genau das wollen Sie vermeiden.

29:05.780 --> 29:08.600
Und das kriegen Sie am besten dann hin, wenn Sie keinem verraten, wie

29:08.600 --> 29:09.640
das intern funktioniert.

29:10.420 --> 29:11.760
Das behalten Sie einfach für sich.

29:13.980 --> 29:16.920
Im Normalfall hat ein Modul mehrere Unterprogramme.

29:17.220 --> 29:21.280
Das heißt, es gibt verschiedene Dinge, die so ein Modul tut.

29:21.920 --> 29:23.140
Das ist nicht so furchtbar überraschend.

29:24.020 --> 29:27.940
Und wenn Sie mehrere Unterprogramme in einem Modul haben, dann sollten

29:27.940 --> 29:31.100
Sie die natürlich bitte so zusammenfassen, dass die einen Zusammenhang

29:31.100 --> 29:31.420
haben.

29:31.660 --> 29:34.840
Das ist das Gleiche wie im letzten Kapitel mit den Paketen.

29:34.840 --> 29:38.740
Wenn Sie mehrere Klassen zu einem Paket zusammenfassen, dann sollten

29:38.740 --> 29:40.440
die Klassen was miteinander zu tun haben.

29:41.240 --> 29:45.520
Wenn Sie mehrere Teilmodule zu einem großen Modul zusammenpacken, dann

29:45.520 --> 29:47.700
sollten die Teilmodule was miteinander zu tun haben.

29:48.560 --> 29:53.260
Das ist eigentlich völlig einleuchtend, aber Sie sollten es sich ins

29:53.260 --> 29:58.340
Gedächtnis rufen, wenn Sie mal denken, das ist hier Verschiedenes.

30:00.500 --> 30:04.800
Verschiedenes ist kein guter Modulname, weil vermutlich hat das, was

30:04.800 --> 30:06.420
da drin ist, nicht viel miteinander zu tun.

30:07.420 --> 30:08.000
Blöde Idee.

30:08.980 --> 30:11.620
Und Sie sollten es irgendwie hinkriegen, dass ein Modul für sich

30:11.620 --> 30:15.040
genommen, einzeln betrachtet, voll verstehbar ist.

30:15.420 --> 30:17.280
Das kennen Sie auch schon aus dem Entwurfsteil.

30:17.380 --> 30:21.120
Ich habe Ihnen gesagt, ein Klassendiagramm von einem Paket sollte auf

30:21.120 --> 30:22.480
eine, die in der Vierseite passen.

30:23.400 --> 30:26.720
Das ist natürlich deswegen so, oder das soll deswegen so sein, damit

30:26.720 --> 30:28.100
Sie es komplett verstehen können.

30:28.920 --> 30:30.220
Am besten auf einen Blick.

30:30.600 --> 30:31.960
Das ist bei einem Modul ganz genauso.

30:34.940 --> 30:37.100
Ein Modul, jetzt haben wir eine schöne Definition.

30:38.020 --> 30:40.360
Wer von Ihnen hat vor, in die mündliche Nachprüfung zu kommen?

30:42.600 --> 30:44.140
Das ist eine sehr gute Einstellung.

30:44.660 --> 30:47.620
Wenn es doch jemanden trifft, solche Definitionen einfach mal

30:47.620 --> 30:48.800
auswendig parat haben.

30:50.860 --> 30:53.180
Aber am besten schreiben Sie einfach die Klausur mit und bestehen.

30:53.260 --> 30:54.220
Dann brauchen Sie das gar nicht.

30:54.820 --> 30:58.860
Das Modul ist eine Menge von Programmelementen, die nach dem

30:58.860 --> 31:01.580
Geheimnisprinzip gemeinsam entworfen werden.

31:04.420 --> 31:06.600
Wer weiß, was das Geheimnisprinzip ist?

31:09.420 --> 31:12.640
Ich meine jetzt nicht Wikileaks und Snowden, sondern das echte

31:12.640 --> 31:14.300
Softwaretechnik -Geheimnisprinzip.

31:15.180 --> 31:15.880
Lieber an der Erste.

31:17.540 --> 31:18.200
Möchten Sie es sagen?

31:18.320 --> 31:18.720
Ja, genau.

31:30.070 --> 31:30.550
Okay.

31:32.270 --> 31:33.890
Sie müssten ein bisschen lauter sprechen.

31:34.070 --> 31:36.450
Ich wiederhole mal, was bei mir angekommen ist.

31:36.850 --> 31:41.570
Herr Kommilitone sagt, das Geheimnisprinzip heißt, ich mache bei

31:41.570 --> 31:43.250
Klassen die ganzen Variablen auf private.

31:43.670 --> 31:45.130
Dann gebe ich Methoden dafür raus.

31:45.590 --> 31:48.270
Die sind dann public, auf die man zugreifen kann, damit so eine Art

31:48.270 --> 31:49.130
Kapselung entsteht.

31:50.030 --> 31:51.250
Hatten Sie noch mehr gesagt?

31:53.590 --> 31:53.770
Nee.

31:54.510 --> 31:55.030
Okay.

31:57.010 --> 31:58.970
Was privat sein muss, soll privat sein.

31:59.270 --> 32:00.550
Das ist doch wieder ein bisschen Snowden.

32:02.290 --> 32:04.150
Aber das ist genau richtig, was Sie sagen.

32:04.450 --> 32:08.290
Die Frage ist nur, was privat sein muss, soll privat sein.

32:08.870 --> 32:10.350
Was soll denn alles privat sein?

32:10.850 --> 32:12.110
Das werden wir uns mal noch anschauen.

32:13.010 --> 32:18.550
Das Geheimnisprinzip heißt, jedes Modul verbirgt eine wichtige

32:18.550 --> 32:21.350
Entwurfsentscheidung hinter einer wohldefinierten Schnittstelle.

32:22.130 --> 32:26.270
Und das Wichtige ist, die Schnittstelle ändert sich nicht, wenn Sie

32:26.270 --> 32:27.630
die Entwurfsentscheidung ändern.

32:29.710 --> 32:33.330
Das Wichtige ist, dass die Schnittstelle sich nicht ändert, wenn Sie

32:33.330 --> 32:34.230
die Entscheidung ändern.

32:35.170 --> 32:38.250
Das klingt ein bisschen blöd, aber ich zeige Ihnen mal, was das

32:38.250 --> 32:40.430
eigentlich heißt oder was das heißen kann.

32:41.290 --> 32:44.750
Wir haben hier eine kleine Klasse, die heißt Strecke ohne Geheimnis.

32:46.370 --> 32:48.450
Soll verdeutlichen, dass die keine Geheimnisse hat.

32:48.450 --> 32:51.050
Alle Programmteile können auf alles zugreifen.

32:51.610 --> 32:55.710
Insbesondere Start- und Endpunkt mit X- und Y-Koordinaten sind völlig

32:55.710 --> 32:56.070
public.

32:56.790 --> 32:59.570
Das heißt, jeder kann mit dieser Strecke machen, was er will.

32:59.830 --> 33:02.630
Es ist ja auch völlig klar, wie das zu benutzen ist.

33:03.230 --> 33:05.850
Wer wird da Fragen haben?

33:06.690 --> 33:10.090
Das ist keine besonders gute Idee, weil Sie können zum Beispiel, wenn

33:10.090 --> 33:14.810
Sie parallel arbeiten, zwei Fäden haben, die da gleichzeitig drauf

33:14.810 --> 33:15.310
zugreifen.

33:16.610 --> 33:19.090
Und Sie kriegen noch nicht mal was mit, dass die gleichzeitig

33:19.090 --> 33:19.610
zugreifen.

33:19.710 --> 33:20.550
Das ist ein bisschen unschön.

33:22.090 --> 33:25.250
Ihr Kommilitone hat gesagt, alles, was privat sein soll, soll privat

33:25.250 --> 33:25.530
sein.

33:25.910 --> 33:28.110
Dann machen wir mal Getter und Setter drumherum.

33:29.890 --> 33:31.290
Da haben wir jetzt Kapselung.

33:31.890 --> 33:32.690
Das ist völlig richtig.

33:32.850 --> 33:36.170
Das heißt, wir haben jetzt immer noch Startpunkt X und Y, Endpunkt X

33:36.170 --> 33:37.450
und Y und die sind jetzt private.

33:38.270 --> 33:40.670
Und dafür geben wir einfach mal Public Getter und Setter an.

33:42.270 --> 33:43.390
Das ist gekapselt.

33:43.390 --> 33:44.770
Ist das geheim?

33:47.070 --> 33:50.710
Haben wir hier das Geheimnisprinzip gut umgesetzt?

33:53.310 --> 33:54.650
Hätten Sie das so gebaut?

33:57.350 --> 33:57.830
Vielleicht.

34:15.700 --> 34:19.900
Der Kommilitone sagt, das ist keine so furchtbar gute Idee, weil zum

34:19.900 --> 34:23.180
Beispiel, wenn ich den Startpunkt ändere, dann kann ich in dem Fall

34:23.180 --> 34:27.120
hier einfach den X-Wert ändern und den Y-Wert stehen lassen.

34:27.820 --> 34:30.640
Das heißt so viel wie, ich habe nur die X-Koordinate verändert.

34:30.940 --> 34:34.380
Wenn ich aber beides ändern will, dann muss ich zwei Methodenaufrufe

34:34.380 --> 34:35.980
machen und das ist schon nicht mehr atomar.

34:36.400 --> 34:38.240
Haben Sie da noch eine Anmerkung dazu?

34:39.860 --> 34:40.000
Ja.

34:49.920 --> 34:50.240
Okay.

34:50.640 --> 34:53.760
Der Kommilitone merkt an, es könnte ja sein, den Startpunkt will man

34:53.760 --> 34:55.120
überhaupt nicht verändern dürfen.

34:56.840 --> 34:59.540
Und dann könnte jetzt immer noch jemand hingehen und den einfach

34:59.540 --> 35:00.720
manipulieren.

35:00.720 --> 35:03.440
Ja, das ist auch ein Problem, aber das hängt ein bisschen von den

35:03.440 --> 35:04.340
Anforderungen ab.

35:04.740 --> 35:06.400
Aber das könnte ein Problem sein.

35:07.600 --> 35:10.740
Der Kernpunkt ist, wir haben hier immer noch X- und Y-Koordinate

35:10.740 --> 35:11.340
getrennt.

35:11.440 --> 35:13.000
Das ist genau das, was Sie gesagt haben.

35:13.400 --> 35:17.380
Und wir haben keinen semantischen Zusammenhang zwischen X und Y.

35:17.740 --> 35:22.080
Das sind halt zwei Int-Variablen und die kann ich getrennt voneinander

35:22.080 --> 35:22.380
setzen.

35:22.840 --> 35:25.780
Und dass die zusammengehören, das gibt mir die API nicht vor.

35:27.360 --> 35:29.880
Schöner wäre es, wenn ich einen Punkt hätte.

35:30.200 --> 35:31.280
Also eine Punktklasse.

35:31.480 --> 35:33.040
Die besteht natürlich aus X und Y.

35:33.880 --> 35:37.320
Und dann kann ich den Startpunkt setzen und ich kann ihn mir geben

35:37.320 --> 35:37.580
lassen.

35:37.900 --> 35:40.700
Und ich kann auch sowas wie die Länge ausrechnen lassen von dem

35:40.700 --> 35:41.580
Linienobjekt.

35:41.820 --> 35:45.100
Ich kann also immer noch all das tun, was ich vorher mit meinen vier

35:45.100 --> 35:46.920
Int -Variablen auch tun konnte.

35:47.280 --> 35:51.760
Nur, dass ich jetzt sicher bin, dass von außen nur noch semantisch

35:51.760 --> 35:53.740
sinnvoll darauf zugegriffen wird.

35:54.220 --> 35:57.940
Dieses Problem, dass ich jetzt die X-Koordinate ändere und die Y

35:57.940 --> 36:00.580
nicht, das kann schon nicht mehr auftreten, weil ich muss einen Punkt

36:00.580 --> 36:01.040
übergeben.

36:01.200 --> 36:02.100
Und er hat immer beides.

36:03.160 --> 36:04.360
Das heißt, es ist schon toller.

36:04.960 --> 36:06.620
Und was kann ich jetzt machen?

36:07.200 --> 36:09.060
Jetzt kann ich die Entwurfsentscheidung ändern.

36:09.720 --> 36:13.340
Die Entwurfsentscheidung für diese Linie ist, ich speichere mir intern

36:13.340 --> 36:14.680
den Start- und den Endpunkt.

36:16.260 --> 36:19.200
Kennt jemand noch eine andere Möglichkeit, eine Linie zu speichern?

36:23.160 --> 36:23.600
Ehrlich?

36:23.700 --> 36:23.940
Niemand?

36:25.300 --> 36:26.940
Sie haben gerade...

36:33.010 --> 36:36.570
Ihr Kommilitone sagt, ein Punkt, ein Winkel und eine Länge.

36:37.270 --> 36:40.630
Das ist zufällig genau das, was wir hier hinten gemacht haben.

36:41.270 --> 36:45.830
Und was Sie hier sehen ist, ich habe jetzt hier zwei Double-Variablen.

36:45.950 --> 36:48.350
Ich habe immer noch einen Punkt als Startpunkt, aber dann eben Länge

36:48.350 --> 36:48.850
und Winkel.

36:49.530 --> 36:52.610
Wie auch immer man Winkel in der Gleitkommazahl angeben mag.

36:52.970 --> 36:55.550
Das ist jetzt nicht so wirklich gut dokumentiert.

36:55.550 --> 37:01.870
Aber das ist völlig egal, weil die Methode SetEndpunkt mit Punkt als

37:01.870 --> 37:03.730
Parameter, die ist immer noch da.

37:04.410 --> 37:06.510
Die Schnittstelle nach außen, die hat sich nicht geändert.

37:06.910 --> 37:09.770
Ich kann immer noch mit zwei Punkten eine Linie machen und wie das

37:09.770 --> 37:14.070
intern dargestellt wird, das überlasse ich dem Linienentwickler.

37:14.750 --> 37:17.810
Und die Länge, die kann ich jetzt viel einfacher zurückgeben, weil die

37:17.810 --> 37:19.150
habe ich ja explizit gespeichert.

37:19.470 --> 37:22.310
Die muss ich nicht mehr ausrechnen, wie in diesem Beispiel.

37:22.910 --> 37:26.850
Man kann natürlich sagen, das ist nicht furchtbar aufwendig, diese

37:26.850 --> 37:29.990
Wurzel auszurechnen, aber das kann man sich natürlich sparen.

37:30.470 --> 37:33.730
Wenn man praktisch nur die Länge abfragt von Linien und sonst nichts

37:33.730 --> 37:36.690
mit denen macht, dann ist es vielleicht praktisch, wenn man die schon

37:36.690 --> 37:37.670
zwischengespeichert hat.

37:38.650 --> 37:42.230
Und diese Entscheidung, die kann man einfach treffen und ändern und

37:42.230 --> 37:44.950
wieder ändern und nochmal revidieren, wenn man die Schnittstelle

37:44.950 --> 37:46.610
vorher klar definiert hat.

37:47.550 --> 37:50.230
Ist Ihnen klar, warum das Geheimnisprinzip eine gute Idee ist?

37:52.330 --> 37:53.670
Wenigstens ein bisschen nicken?

37:55.130 --> 37:55.530
Okay.

37:57.030 --> 38:01.670
Die Idee ist, wenn Sie voraussehbare Änderungen haben, das ist sowas

38:01.670 --> 38:03.530
wie, wie speichere ich denn eine Linie?

38:04.090 --> 38:06.910
Das soll möglichst ohne jegliche Änderung an den Schnittstellen

38:06.910 --> 38:07.690
passieren können.

38:08.370 --> 38:12.930
Und je unwahrscheinlicher, je unvorhersehbar so eine Änderung an der

38:12.930 --> 38:18.630
internen Repräsentation wird, desto wahrscheinlicher dürfen sich die

38:18.630 --> 38:19.530
Schnittstellen ändern.

38:19.530 --> 38:24.110
Das heißt, wenn ganz seltene Änderungen kommen, dann dürfen wir das

38:24.110 --> 38:24.550
doch machen.

38:25.490 --> 38:29.010
Aber das soll dann bitte auch möglichst nicht überall passieren,

38:29.130 --> 38:30.570
sondern nur an lokalen Stellen.

38:32.450 --> 38:35.690
Die Anmerkung 1 ist genau das, was Ihr Kommilitone zu Beginn gesagt

38:35.690 --> 38:35.990
hat.

38:36.450 --> 38:41.010
Das Geheimnisprinzip führt praktisch immer dazu, dass Sie Attribute

38:41.010 --> 38:45.790
privat abspeichern, das heißt private Instanzvariablen haben und

38:45.790 --> 38:49.450
Zugriffsmethoden bereitstellen, damit man mit diesen Attributen

38:49.450 --> 38:50.110
arbeiten kann.

38:50.890 --> 38:52.170
Das ist aber nicht alles.

38:52.770 --> 38:57.530
Wie wir gesehen haben, wenn ich Z-Startwert X und Z-Startwert Y mache,

38:57.730 --> 39:01.450
dann habe ich zwar gekapselt, aber verborgen habe ich nichts.

39:02.850 --> 39:05.430
Also es kommt ein bisschen darauf an, was man damit macht.

39:06.490 --> 39:07.270
Die Anmerkung 2.

39:08.180 --> 39:13.050
Was bedeutet die deprecated Information in der Java-Dokumentation?

39:14.810 --> 39:16.050
In diesem Kontext?

39:25.000 --> 39:28.540
Ihr Kommilitone sagt, die Methode, die damit gekennzeichnet ist, die

39:28.540 --> 39:30.020
ist veraltet und wurde ersetzt.

39:32.000 --> 39:33.420
Vielleicht ersetzt, ja.

39:33.920 --> 39:36.540
Vielleicht ein bisschen spezieller auf den Modulteil.

39:40.740 --> 39:43.420
Das ist genau das, was Sie gerade sagen.

39:43.420 --> 39:47.140
Das ist eine Warnung an die Leute, die das benutzen, nämlich Achtung,

39:47.980 --> 39:51.300
hier hat sich was geändert oder hier wird sich was ändern.

39:51.980 --> 39:55.700
Benutzt diese Methode nicht mehr, weil das ist eine Schnittstelle, die

39:55.700 --> 39:56.540
werde ich ändern müssen.

39:57.480 --> 39:58.620
Richte dich darauf ein.

40:00.760 --> 40:04.580
Das ist quasi die Vorankündigung zu, naja, die Schnittstelle, die war

40:04.580 --> 40:07.780
doch nicht so gut nach dem Geheimnisprinzip entworfen, wie ich das

40:07.780 --> 40:08.480
eigentlich dachte.

40:09.520 --> 40:11.840
Also wenn Sie sowas treffen, besser nicht benutzen.

40:11.840 --> 40:14.060
Wir haben einfach keine Garantie.

40:16.720 --> 40:19.400
Wie kann ich jetzt meinen Entwurf danach gliedern?

40:19.540 --> 40:22.100
Ich mache mir eine Liste von allen Dingen, die sich wahrscheinlich mal

40:22.100 --> 40:26.460
ändern können oder die ich ändern können will und sortiere die so ein

40:26.460 --> 40:30.340
bisschen, nämlich nach, wie schwierig sind die, wenn ich sie ändern

40:30.340 --> 40:33.540
muss und wie wahrscheinlich ist es, dass die sich ändern.

40:33.920 --> 40:37.000
Und jede dieser Entwurfsentscheidungen packe ich am besten in ein

40:37.000 --> 40:37.320
Modul.

40:38.760 --> 40:43.260
Dann habe ich quasi, jedes Modul kapselt dann eine solche

40:43.260 --> 40:46.260
Entwurfsentscheidung und die Schnittstelle ist sauber.

40:46.440 --> 40:49.020
Und wenn ich nur diese eine Entwurfsentscheidung ändere, dann muss ich

40:49.020 --> 40:50.640
nur in dieses eine Modul greifen.

40:51.580 --> 40:54.880
Es ist eine schlechte Idee, ein Geheimnis über viele Module zu

40:54.880 --> 40:55.360
verteilen.

40:56.120 --> 40:58.880
Weil wenn sich dieses eine Geheimnis ändert, dann müssen Sie alle

40:58.880 --> 41:01.040
betroffenen Module anfassen.

41:01.840 --> 41:05.440
Versuchen Sie das so zu kapseln, dass Sie eine Entwurfsentscheidung in

41:05.440 --> 41:06.560
ein Modul reinstecken.

41:06.560 --> 41:11.160
Das heißt nicht, dass in einem Modul nur ein Geheimnis sein darf.

41:11.740 --> 41:14.000
Aber ein Geheimnis sollte nur in einem Modul sein.

41:19.140 --> 41:20.920
Was sind denn so die Klassiker?

41:21.800 --> 41:23.040
Datenstrukturen, auf jeden Fall.

41:23.540 --> 41:27.420
Alles, was in die Implementierungsdetails reingeht.

41:27.740 --> 41:29.780
Ich hatte vorhin so etwas mit einem Index angerissen.

41:30.460 --> 41:34.420
Wenn Sie sich Indizes auf Speicheradressen speichern, wenn Sie im C

41:34.420 --> 41:37.440
-Feld unterwegs sind, das ist eine gute Idee.

41:37.900 --> 41:39.000
Aber das sollte niemand wissen.

41:41.060 --> 41:44.920
Auch verbergen sollten Sie so Dinge wie Gerätetreiber, alles, was

41:44.920 --> 41:47.340
hardware -nah ist, alles, was betriebssystemnah ist.

41:48.760 --> 41:51.100
Koppeln Sie alles ab, was Windows-spezifisch ist.

41:52.200 --> 41:53.760
Kapseln Sie das am besten in irgendwas rein.

41:53.860 --> 41:56.980
Dann können Sie sich ein äquivalentes Modul bauen für ein anderes

41:56.980 --> 41:57.660
Betriebssystem.

41:58.580 --> 42:01.560
Und müssen nur dieses eine Modul austauschen.

42:03.440 --> 42:06.420
Und alles, was an Basissoftware herangeht.

42:06.760 --> 42:09.880
Datenbanken, Bibliotheken für grafische Benutzeroberflächen.

42:10.340 --> 42:13.160
All das sollten Sie in ein Modul packen, weil es könnte sein, nächste

42:13.160 --> 42:16.120
Woche kommt Ihr Chef und sagt, wir haben die Oracle-Lizenz nicht

42:16.120 --> 42:16.560
verlängert.

42:16.980 --> 42:18.800
Wie schnell können Sie Postgres einsetzen?

42:19.760 --> 42:23.820
Wenn Sie dann sagen, da muss ich jetzt aber die ganze Software

42:23.820 --> 42:26.740
umbauen, weil alle Module, die ich habe, greifen auf die Datenbank zu.

42:26.860 --> 42:27.460
Und zwar direkt.

42:28.480 --> 42:30.000
Das ist nicht so ganz geschickt.

42:30.960 --> 42:32.080
Dann haben Sie ein Problem.

42:32.200 --> 42:34.560
Dann müssen Sie das Wochenende durcharbeiten, mindestens.

42:35.780 --> 42:38.820
Oder Sie überzeugen Ihren Chef davon, doch nochmal die Oracle-Lizenz

42:38.820 --> 42:39.380
zu verlängern.

42:39.840 --> 42:41.360
Aber da brauchen Sie echt gute Argumente.

42:42.360 --> 42:46.480
Wie zum Beispiel, wir sind pleite, weil unsere Software dann nicht

42:46.480 --> 42:48.100
mehr funktioniert, wenn Sie das jetzt so entscheiden.

42:48.900 --> 42:51.580
Aber das sollte natürlich nicht auf Ihrem Mist gewachsen sein.

42:51.740 --> 42:54.400
Sie sollten nicht der Architekt gewesen sein, der das verbrochen hat.

42:55.760 --> 42:56.480
Schlechte Idee.

42:56.480 --> 42:59.460
Es sei denn, Sie sind irgendwo auf CEO-Ebene.

42:59.680 --> 43:00.480
Dann können Sie das machen.

43:00.580 --> 43:01.940
Dann kriegen Sie 100 Millionen Abfindung.

43:03.160 --> 43:06.380
Aber vermutlich als CEO werden Sie keine Architektur mehr bauen.

43:08.220 --> 43:11.160
Also all diese Dinge, die hier draufstehen, merken Sie sich die.

43:11.260 --> 43:13.840
Wenn Sie sowas treffen, am besten Kapseln.

43:14.280 --> 43:17.580
Nicht nach außen rausgeben, wie man das intern benutzt hat.

43:18.980 --> 43:19.280
Okay.

43:19.600 --> 43:22.140
Es gibt noch weitere Ein- und Ausgabeformate.

43:22.320 --> 43:24.260
Das ist das gleiche wie mit der Datenbank.

43:24.260 --> 43:27.480
Wenn Sie jemandem verraten, wie Ihr Binärdateiformat funktioniert und

43:27.480 --> 43:30.240
er greift da direkt rein, dann können Sie es nicht mehr ändern.

43:31.280 --> 43:31.500
Blöd.

43:33.540 --> 43:39.140
Text von Dialogen, Beschriftungen, all das, was Sprachunabhängigkeit

43:39.140 --> 43:40.400
ermöglicht, das sollten Sie rauskapseln.

43:41.340 --> 43:44.860
Gehen Sie davon aus, dass Sie keine Anwendung sinnvoller Größe mehr

43:44.860 --> 43:47.940
bauen werden, die ausschließlich auf Deutsch vertrieben wird.

43:48.080 --> 43:49.500
Oder ausschließlich auf Englisch.

43:50.080 --> 43:53.180
Sie wollen die Software immer so bauen, dass Sie sie am besten auf dem

43:53.180 --> 43:54.480
ganzen Globus verkaufen können.

43:55.040 --> 43:58.140
Und zwar ohne, dass Sie die Software komplett umarbeiten müssen.

43:58.760 --> 44:01.320
Es sollte reichen, dass Sie ein Modul austauschen, in dem alle

44:01.320 --> 44:03.340
Bezeichner drin stehen, die man in der GUI sieht.

44:06.380 --> 44:07.820
Ja, genau.

44:08.700 --> 44:11.940
Haben Sie Fragen bis hierhin, was man denn so verbergen sollte und

44:11.940 --> 44:12.140
warum?

44:15.780 --> 44:16.180
Okay.

44:17.980 --> 44:20.680
Wenn Sie das alles getan haben, müssen Sie es in den Modulführer

44:20.680 --> 44:21.180
reinschreiben.

44:21.180 --> 44:23.140
Sie müssen erklären, was Sie da gemacht haben.

44:23.460 --> 44:26.840
Sie müssen erklären, was sind die Entwurfsentscheidungen, die

44:26.840 --> 44:27.600
gekapselt werden?

44:27.800 --> 44:28.900
Wie werden die gekapselt?

44:29.420 --> 44:31.540
Was ist die Funktion überhaupt von diesem Modul?

44:32.060 --> 44:32.960
Was soll das denn tun?

44:33.680 --> 44:39.240
Und wenn dieses Modul in weitere Untermodule aufgeteilt ist, dann

44:39.240 --> 44:40.900
sollten Sie natürlich die Struktur erklären.

44:41.520 --> 44:45.000
Das heißt, Sie haben dieselbe Aufgabe noch mal innerhalb des Moduls

44:45.000 --> 44:46.720
wie innerhalb der gesamten Architektur.

44:47.940 --> 44:49.420
Das ist nicht so furchtbar überraschend.

44:49.420 --> 44:50.620
Sie müssen es halt dokumentieren.

44:50.740 --> 44:55.380
Gehen Sie davon aus, Sie machen Feierabend und laufen vor einen Bus.

44:56.200 --> 44:58.060
Dann sollte Ihre Firma nicht pleite gehen.

44:59.120 --> 45:01.340
Das ist so der Wunsch, den man hat an Dokumentation.

45:04.800 --> 45:07.580
Deswegen überlegen Sie sich, dass Sie keine Duplikate da reinmachen,

45:07.820 --> 45:09.220
weil Duplikate muss man pflegen.

45:10.580 --> 45:11.460
Vermeiden Sie Lücken.

45:12.000 --> 45:14.600
Natürlich ist es toll, wenn Sie der Einzige in der Firma sind, der

45:14.600 --> 45:16.320
irgendwas Spezielles erklären kann.

45:16.320 --> 45:19.000
Aber aus Firmensicht will man das nicht haben.

45:20.180 --> 45:23.000
Insbesondere, wenn Sie mal ein Team von Entwicklern oder von

45:23.000 --> 45:26.880
Architekten beaufsichtigen und stellen fest, da ist immer eine Lücke.

45:27.140 --> 45:29.420
Immer wenn der Architekt unterwegs ist, habe ich eine Lücke in der

45:29.420 --> 45:30.140
Dokumentation.

45:30.400 --> 45:31.520
Dann hauen Sie dem auf die Finger.

45:32.420 --> 45:34.440
Das ist Ihr Job, aufzupassen, dass das nicht passiert.

45:36.120 --> 45:39.140
Das liefert einerseits natürlich eine Zerlegung des Problems.

45:39.420 --> 45:42.200
Wenn man diesen Modulführer liest, dann weiß man, wie sind die

45:42.200 --> 45:45.260
Einzelschritte, die ich durchführen muss, um das Problem zu lösen.

45:45.720 --> 45:49.460
Und wenn Sie hinterher das Produkt ausrollen und es in den

45:49.460 --> 45:54.720
Wartungszweig reinfällt, also andere Entwickler sich um Fehlerbehebung

45:54.720 --> 45:58.160
bemühen müssen und um Aktualisierung, weil sich das Betriebssystem

45:58.160 --> 46:01.720
darunter geändert hat oder was auch immer, dann wollen Sie, dass

46:01.720 --> 46:04.340
dieses Wartungsteam effizient arbeiten kann.

46:05.160 --> 46:06.460
Dafür braucht es Dokumentation.

46:06.820 --> 46:08.660
Und da tut es nicht ein zäherter Pfeil.

46:09.260 --> 46:10.820
Da können Sie einfach nichts mit anfangen.

46:10.820 --> 46:12.700
Sie brauchen ein bisschen mehr Kontext.

46:14.960 --> 46:18.020
Die Schnittstellen, die sollten Sie so definieren, dass Sie am Ende

46:18.020 --> 46:18.960
eine Blackbox haben.

46:20.660 --> 46:28.580
Schreiben Sie hin, was sind die Methoden oder die Prozeduren, die man

46:28.580 --> 46:29.300
aufrufen kann.

46:29.600 --> 46:31.820
Was sind die Eingabeparameter, was sind die Rückgaben.

46:33.680 --> 46:37.360
Und sorgen Sie, wie gesagt, dafür, dass die Schnittstellen invariant

46:37.360 --> 46:39.440
sind, wenn irgendwas sich an den Internen ändert.

46:39.920 --> 46:42.680
Vielleicht kennen Sie die Internen noch gar nicht, wenn Sie entwerfen.

46:43.180 --> 46:46.940
Dann sind Sie gezwungen, das so zu machen, dass es änderbar ist.

46:49.660 --> 46:50.800
Was kriegt man also?

46:50.920 --> 46:52.860
Eine Liste der öffentlichen Programmelemente.

46:53.900 --> 46:56.200
Erinnern Sie sich mal, was Sie alles in der Java-Dokumentation

46:56.200 --> 46:56.500
kriegen.

46:57.120 --> 47:00.900
Sie kriegen die Ein- und Ausgabeformate, wenn das denn ein Ein- und

47:00.900 --> 47:03.020
Ausgabemodul ist, sprich die Dateiformate.

47:03.800 --> 47:07.300
Sie kriegen Parameter und Rückgabewerte von Unterprogrammen oder

47:07.300 --> 47:08.240
Operationen.

47:09.100 --> 47:12.980
Sie kriegen eine Beschreibung des Effekts, also was tut das Ding.

47:14.800 --> 47:18.520
Und Sie kriegen zum Beispiel auch gesagt, was sind denn Fehler, die da

47:18.520 --> 47:21.300
auftreten können und wie werden die behandelt oder wie müssen die

47:21.300 --> 47:21.980
behandelt werden.

47:23.260 --> 47:26.640
Und was passiert, wenn da eine Ausnahme auftritt, die eben nicht

47:26.640 --> 47:30.500
behandelt wird, modulintern, sondern die man außen irgendwie aufräumen

47:30.500 --> 47:30.720
muss.

47:32.060 --> 47:35.060
Das ist schon sehr stark, oder das sieht schon sehr stark nach dem

47:35.060 --> 47:37.300
aus, was Sie kriegen, wenn Sie einfach Java-Doc aufmachen.

47:38.740 --> 47:42.580
Das heißt, wenn Sie ein Java-System sinnvoll implementieren, dann

47:42.580 --> 47:44.480
kriegen Sie große Teile davon einfach geschenkt.

47:44.980 --> 47:47.660
Sie müssen halt noch den Methodenkommentar dazuschreiben oder den

47:47.660 --> 47:48.480
Klassenkommentar.

47:48.780 --> 47:53.380
Dann sind Sie schon sehr nah an dem dran, was hier als Modulführer

47:53.380 --> 47:57.100
oder als Modulschnittstellenbeschreibung gefordert wird.

47:59.400 --> 48:00.820
Haben Sie Fragen bis hierhin?

48:02.740 --> 48:04.080
Dann habe ich eine Frage.

48:04.380 --> 48:06.380
Wissen Sie, was ein Quick-Index ist?

48:06.820 --> 48:08.600
Haben Sie sowas schon mal in der Hand gehabt?

48:10.240 --> 48:11.540
Keywords in Context.

48:14.540 --> 48:17.020
Das hat man benutzt, als man noch Bücher benutzt hat.

48:18.640 --> 48:22.300
Ich weiß nicht, ob Sie schon mal so einen Index in einem Buch gesehen

48:22.300 --> 48:28.140
haben, aber das ist, sagen wir mal, ein recht interessantes Problem

48:28.140 --> 48:33.060
und die Aufgabe, diesen Index zu bauen, ist in Anführungszeichen

48:33.060 --> 48:33.500
schwierig.

48:33.960 --> 48:36.800
Und was ich Ihnen jetzt zeigen werde, das ist eine Fallstudie, die

48:36.800 --> 48:38.820
ist, glaube ich, von 1970.

48:40.120 --> 48:44.820
Das heißt, damals waren Rechner irgendwie teuer.

48:45.860 --> 48:50.080
Man musste da Millionen investieren und dann hat man 600K Speicher

48:50.080 --> 48:50.480
bekommen.

48:52.600 --> 48:55.320
Das heißt, sich Gedanken darüber machen, wie man das schnell und

48:55.320 --> 48:59.020
effizient und speicherschonend implementiert, das war lohnenswert,

48:59.340 --> 49:02.440
weil man musste dann nicht beim Hardwarehersteller nochmal einen LKW

49:02.440 --> 49:03.660
-Speicher reinrollen lassen.

49:04.820 --> 49:05.940
Für 100K.

49:08.400 --> 49:13.840
Deswegen hat man sich eben Ingenieure, Informatiker hingesetzt und hat

49:13.840 --> 49:14.800
die das sinnvoll machen lassen.

49:15.240 --> 49:17.200
Jetzt aber, was ist ein Quick-Index?

49:17.800 --> 49:22.000
In einem Quick-Index, da stehen Wörter drin, die man suchen möchte,

49:22.160 --> 49:23.740
sowas wie ein Index in einem Buch.

49:24.600 --> 49:27.480
Aber wir gehen nicht mehr von einzelnen Wörtern aus, sondern von

49:27.480 --> 49:29.540
ganzen Titeln, zum Beispiel von Büchern.

49:30.320 --> 49:34.380
Und Sie möchten zum Beispiel suchen können nach Harry Potter.

49:35.980 --> 49:39.460
Das heißt, Sie wollen, dass im Index unter H Harry Potter unter

49:39.460 --> 49:40.520
Ordnung des Phönix steht.

49:41.360 --> 49:43.900
Wenn Sie aber nicht mehr so genau wissen, wie der Zauberer hieß, aber

49:43.900 --> 49:47.380
da war irgendwas mit diesem Phönix, dann wollen Sie nach P gehen und

49:47.380 --> 49:50.780
da muss dann stehen Phönix, Harry Potter unter Ordnung des.

49:51.740 --> 49:54.960
Das heißt, Sie brauchen von diesen Titeln die ganzen zirkulären

49:54.960 --> 49:55.600
Verschiebungen.

49:56.460 --> 49:59.800
Erst in der normalen Reihenfolge, dann das erste Wort weglöschen und

49:59.800 --> 50:03.000
ans Ende dran und so weiter, bis Sie da einmal durchrotiert sind.

50:04.200 --> 50:07.440
Und dann haben Sie alle Verschiebungen und die werden alphabetisch

50:07.440 --> 50:08.900
sortiert und dann haben Sie Ihren Index.

50:10.280 --> 50:12.480
Ich nehme an, so einigermaßen ist klar, was das ist.

50:13.100 --> 50:18.640
Hier haben wir mal ein Beispiel und wenn man diese Titel da reinsetzt,

50:18.820 --> 50:20.040
dann kommt dieser Index raus.

50:21.000 --> 50:23.600
Was in diesem Index jetzt passiert ist, ist genau das, was ich Ihnen

50:23.600 --> 50:24.260
gesagt habe.

50:25.160 --> 50:26.920
Es ist nur ein bisschen komisch dargestellt.

50:27.300 --> 50:31.680
Das erste Wort in der Zeile Ihres Indexes, das Sie in der Hand haben,

50:31.760 --> 50:32.880
das ist das Großgedruckte.

50:33.640 --> 50:38.300
Das heißt, es gibt ein Buch, das heißt Flug des Phönix, der.

50:38.940 --> 50:42.460
Und es gibt Klöster, Orden und.

50:43.620 --> 50:44.900
So muss man das lesen.

50:45.100 --> 50:48.000
Das heißt, alles was links steht, gehört eigentlich rechts hinten dran

50:48.000 --> 50:48.440
geklebt.

50:49.060 --> 50:52.840
Und Sie sehen, da sind natürlich alle Verschiebungen drin, abgesehen

50:52.840 --> 50:56.360
davon, dass die Stoppwörter übersprungen sind.

50:56.660 --> 51:02.060
Es gibt keine Einträge, die mit der, die, das und so weiter anfangen.

51:02.640 --> 51:03.660
Das will man nicht haben.

51:04.200 --> 51:07.600
Jetzt ist aber die Frage, wie kriegt man so ein Index hübsch hin?

51:08.320 --> 51:10.280
Und speichersparend und alles.

51:11.180 --> 51:13.460
Man könnte natürlich hingehen und sagen, okay, ich habe hier einen

51:13.460 --> 51:18.080
Titel, dann verschiebe ich den jeweils um ein Wort.

51:18.460 --> 51:21.040
Wenn ein Stoppwort am Anfang ist, dann überspringe ich diesen Eintrag.

51:21.160 --> 51:23.740
Und wenn kein Stoppwort am Anfang ist, dann speichere ich mir das

51:23.740 --> 51:25.780
Ganze und mache die nächste Verschiebung.

51:26.200 --> 51:29.580
Das führt natürlich dazu, dass ich jeden Titel vielfach abspeichern

51:29.580 --> 51:29.820
muss.

51:30.360 --> 51:33.480
Nämlich so oft, wie Wörter drin sind, die keine Stoppwörter sind.

51:34.820 --> 51:37.300
Und das ist ein bisschen ungeschickt, wenn Speicher Phantastilliaden

51:37.300 --> 51:37.800
kostet.

51:38.780 --> 51:40.280
Wir brauchen also eine andere Lösung.

51:41.360 --> 51:44.100
Und diese andere Lösung, die ist ein bisschen umfangreich.

51:44.840 --> 51:45.880
Ich habe noch ein anderes Beispiel.

51:46.520 --> 51:48.160
Das ist aber dasselbe in grün.

51:48.300 --> 51:51.620
Ich weiß nicht, wer und warum diese Folie da eingefügt hat.

51:51.760 --> 51:55.520
Aber Sie sehen, hier gibt es jetzt eine Verschiebung, oder einen Titel

51:55.520 --> 51:56.460
mit vier Wörtern.

51:56.460 --> 51:58.020
Und dazu gibt es vier Verschiebungen.

51:58.180 --> 52:00.420
Das heißt, wir haben echt den Speicherbedarf vervierfacht.

52:01.700 --> 52:03.700
Und das ist kein besonders langer Buchtitel.

52:04.480 --> 52:07.240
Denken Sie mal an akademische Werke, wo dann der Untertitel noch zwei

52:07.240 --> 52:07.720
Sätze hat.

52:08.420 --> 52:09.180
Das wird echt teuer.

52:10.040 --> 52:11.280
Deswegen will man das nicht haben.

52:12.400 --> 52:17.360
Und es gibt einen wunderschönen Entwurf, der wirklich ganz großartig

52:17.360 --> 52:18.340
ist und viele Pfeile hat.

52:19.200 --> 52:22.760
Deswegen gehen wir da mal stückweise durch und ich erkläre Ihnen, wie

52:22.760 --> 52:23.660
das funktionieren kann.

52:23.920 --> 52:26.260
Und dann sagen Sie mir, ob das eine gute Idee war, das so zu machen.

52:27.220 --> 52:31.000
Oben drüber, ganz oben, das Hauptmodul, das ist der Treiber.

52:31.620 --> 52:34.900
Der ist dafür zuständig, dass dieser ganze Ablauf orchestriert wird.

52:35.020 --> 52:37.380
Der kümmert sich darum, dass die Module in der richtigen Reihenfolge

52:37.380 --> 52:38.600
aufgerufen werden usw.

52:39.520 --> 52:41.720
Und jetzt gucken wir uns diese Hauptzeile an.

52:42.040 --> 52:44.100
Das heißt, ganz links gibt es die Eingabe.

52:44.420 --> 52:45.980
Da fließen die Titel rein.

52:46.220 --> 52:47.520
Das heißt, eine Textdatei.

52:47.620 --> 52:48.960
In jeder Zeile steht ein Titel.

52:50.080 --> 52:51.960
Dann muss das Ganze verschoben werden.

52:51.960 --> 52:54.480
Jeder Titel jeweils einmal komplett rum.

52:54.960 --> 52:58.180
Dann muss das ganze Ergebnis nach dem Alphabet sortiert werden.

52:58.540 --> 53:00.000
Und dann wollen wir das noch ausgeben.

53:01.540 --> 53:05.380
Das ist einfach so das, was man tun muss, um einen Quick Index

53:05.380 --> 53:05.960
herzustellen.

53:06.640 --> 53:11.980
Und jetzt kommt die untere Hälfte der eigentlichen Implementierung.

53:13.020 --> 53:14.060
Und da passiert die Magie.

53:15.220 --> 53:16.360
Das ist ganz großartig.

53:16.860 --> 53:17.960
Es gibt einen Zeilenspeicher.

53:19.100 --> 53:21.360
Da wird jeder Titel gespeichert als eine Zeile.

53:22.400 --> 53:24.040
Das ist erstmal nicht furchtbar spannend.

53:24.220 --> 53:25.980
Das ist einfach nur die Textdatei im Hauptspeicher.

53:27.460 --> 53:29.120
Dann gibt es einen Verschieber.

53:29.460 --> 53:33.080
Dieser Verschieber liest die ganzen Zeilen und speichert sich einen

53:33.080 --> 53:34.260
Index auf die Verschiebungen.

53:34.400 --> 53:37.240
Ich zeige Ihnen gleich ein Bild, auf dem Sie sehen, wie dieser Index

53:37.240 --> 53:37.780
funktioniert.

53:38.680 --> 53:43.900
Das heißt, dieser Verschiebeindex, der hier rauskommt, der hat Pointer

53:43.900 --> 53:47.920
auf die einzelnen Verschiebungen, auf diese zyklischen Rotationen in

53:47.920 --> 53:52.140
dem Index drin, ohne dass die einzelnen Zeilen vervielfältigt werden.

53:53.080 --> 53:56.740
Und ganz am Ende wird dieser supergeile Verschiebeindex, der wird dann

53:56.740 --> 53:57.600
noch sortiert.

53:58.240 --> 53:59.840
Dann kommt ein sortierter Index raus.

54:01.120 --> 54:03.800
Das heißt, wir haben hier sehr feingliedrig aufgeschlüsselte

54:03.800 --> 54:06.880
Datenstruktur und wir speichern einmal die gesamte Datei.

54:07.380 --> 54:10.220
Und hier drin, in den beiden Indizes, da sind nur noch Pointer.

54:11.180 --> 54:12.300
Das ist also sehr kompakt.

54:13.320 --> 54:14.400
Jetzt, wie funktioniert das?

54:15.660 --> 54:16.260
Bisschen blöd.

54:16.820 --> 54:18.360
Also, wir lesen das Ganze ein.

54:19.200 --> 54:19.680
Textdatei.

54:20.080 --> 54:21.780
In jeder Zeile steht ein Titel.

54:22.240 --> 54:24.860
Und speichern das im Hauptspeicher.

54:25.700 --> 54:29.920
Zusätzlich merken wir uns für jede Zeile, wo im Hauptspeicher die

54:29.920 --> 54:30.360
anfängt.

54:31.820 --> 54:32.780
Das sieht dann so aus.

54:33.300 --> 54:34.340
Mit dem Abs.

54:34.540 --> 54:34.980
Integer.

54:35.100 --> 54:35.860
Absolute Value.

54:36.080 --> 54:37.540
Aus dem Beispiel von eben.

54:38.300 --> 54:39.620
Das ist im Hauptspeicher.

54:40.340 --> 54:40.820
Abs.

54:40.820 --> 54:43.040
Doppelpunkt ist die Zeichenkette, die gespeichert wird.

54:43.040 --> 54:46.040
Und Backslash 0 ist das Endbyte.

54:46.820 --> 54:48.800
Das sagt, an der Stelle ist vorbei.

54:49.300 --> 54:50.500
Da kommt jetzt das nächste Wort.

54:51.340 --> 54:53.340
Das heißt, da geht es dann direkt weiter.

54:53.460 --> 54:58.100
Da ist kein Speicherplatz zwischendrin, der irgendwie reserviert wird,

54:58.180 --> 55:00.920
aber nicht benutzt, sondern die Wörter werden direkt hintereinander im

55:00.920 --> 55:01.880
Rahmen abgelegt.

55:02.280 --> 55:03.220
So kompakt, wie es geht.

55:04.140 --> 55:08.400
Und der Zeilenindex sagt, die Zeile i fängt hier vorne an.

55:08.900 --> 55:11.340
Und die Zeile i plus 1 fängt hier hinten an.

55:11.340 --> 55:14.840
Da fängt also der nächste Titel an, wo hier Punkt, Punkt, Punkt steht.

55:16.340 --> 55:18.400
Im Rahmen habe ich also jetzt eine Wortliste.

55:19.100 --> 55:20.240
Die ist sehr lang.

55:20.580 --> 55:23.200
Und ich habe viele Zeiger, die sagen mir immer, übrigens, hier fängt

55:23.200 --> 55:26.100
ein Titel an, und da fängt ein Titel an, und da fängt der nächste an.

55:27.300 --> 55:31.380
Also die Liste der Zeiger hier, die ist genauso lang, wie viele Titel

55:31.380 --> 55:33.540
ich habe in meiner Textdatei.

55:34.080 --> 55:35.340
Wie viele Zeilen da drin stehen.

55:37.380 --> 55:39.420
Dann kommt die Geschichte mit dem Verschieben.

55:39.420 --> 55:45.420
Und der Verschieber, der schaut sich jetzt an, der zeigt auch mal

55:45.420 --> 55:47.480
wieder einen Index, das ist ganz praktisch.

55:47.720 --> 55:51.660
Und zwar speichere ich mir die Zeilennummer, also die Nummer des

55:51.660 --> 55:56.420
Titels, der gerade verschoben wird, und die Adresse, und zwar die

55:56.420 --> 55:58.220
Adresse vom ersten Wort in der Verschiebung.

56:00.240 --> 56:03.300
Der erste Eintrag in diesem Index ist also 0.

56:03.400 --> 56:05.860
Wort vom 0.

56:05.980 --> 56:06.320
Titel.

56:07.260 --> 56:10.420
Und der nächste Eintrag ist 0.

56:10.480 --> 56:11.660
Titel, erstes Wort.

56:12.140 --> 56:13.180
Der nächste Eintrag ist 0.

56:13.300 --> 56:14.240
Titel, zweites Wort.

56:15.440 --> 56:18.700
Damit kann ich quasi alle Verschiebungen rekonstruieren.

56:18.800 --> 56:19.940
Ich kann mir die alle ausrechnen.

56:21.040 --> 56:22.120
Nur mit diesem Index.

56:22.640 --> 56:25.340
Das heißt, ich habe jetzt einen Verschiebeindex, der sagt, die erste

56:25.340 --> 56:27.200
Verschiebung, die fängt hier an.

56:27.680 --> 56:29.480
Das ist der Titel in der normalen Reihenfolge.

56:29.720 --> 56:31.980
Dann kommt Abs, Integer, Absolute Value raus.

56:32.820 --> 56:35.660
Der nächste Eintrag, der geht auch immer noch auf den Titel I.

56:36.280 --> 56:37.660
Der fängt bei Integer an.

56:38.360 --> 56:41.360
Also ist die Verschiebung Integer, Absolute Value, Abs.

56:42.640 --> 56:43.240
Und so weiter.

56:44.800 --> 56:46.320
Bis hierhin, denke ich, ist noch klar.

56:46.480 --> 56:50.100
Ich kann jetzt diesen Verschiebeindex hier durchgehen und mir aus dem

56:50.100 --> 56:53.020
Hauptspeicher alle Verschiebungen raussuchen, die es gibt.

56:53.480 --> 56:54.360
Und kann die ausgeben.

56:54.820 --> 56:56.620
Blöd ist, das ist noch nicht sortiert.

56:57.800 --> 57:01.060
Also brauche ich noch einen Sortierer, der mit diesem Index hier

57:01.060 --> 57:01.620
umgehen kann.

57:02.500 --> 57:04.240
Den kann ich ja relativ einfach bauen.

57:04.380 --> 57:05.720
Ich weiß ja, wie der Index funktioniert.

57:06.080 --> 57:10.660
Das heißt, ich nehme ein neues Modul her und sage, okay, die Eingabe

57:10.660 --> 57:14.840
ist, ich nehme die beiden Datenstrukturen, die es da schon gab und

57:15.820 --> 57:18.380
mache im Prinzip das Gleiche wie das Verschiebemodul.

57:18.540 --> 57:21.220
Ich baue einen Index, nur dieser Index, der ist halt sortiert.

57:21.460 --> 57:23.720
Und zwar nach dem Wort, auf das gezeigt wird.

57:24.820 --> 57:28.260
Und damit habe ich natürlich auch erreicht, dass ich die einzelnen

57:28.260 --> 57:30.760
Einträge nicht kopieren muss, sondern ich habe nur nochmal ein Feld

57:30.760 --> 57:32.260
von neuen Zeigern hinzugefügt.

57:33.080 --> 57:36.920
Das sieht also dann so aus, dass ich Zeiger habe, die mir auf den

57:36.920 --> 57:37.960
Verschiebeindex zeigen.

57:38.780 --> 57:43.120
Und das heißt, dieser Eintrag, der mit Abs anfängt, der kommt als

57:43.120 --> 57:43.620
erstes.

57:43.720 --> 57:47.340
Der zweite Eintrag, das ist der, der mit Absolute anfängt.

57:47.600 --> 57:50.260
Der dritte Eintrag, der fängt mit Integer an.

57:50.380 --> 57:53.240
Und der vierte Eintrag, das ist der, der mit Value anfängt.

57:55.800 --> 57:57.520
Das ist einigermaßen okay.

57:57.520 --> 58:00.860
Ich wollte nicht mit diesen ganzen Indizes rumschubsen und mit den

58:00.860 --> 58:02.600
Speicheradressen, aber kann man so machen.

58:03.900 --> 58:06.640
Und, naja, das ist saumäßig kompakt.

58:07.860 --> 58:12.400
Das kaliert zwar in der Größe der Eingabe, weil die muss ich halt im

58:12.400 --> 58:12.880
Rahmen haben.

58:13.420 --> 58:16.780
Das ist halt ungeschickt, aber das muss man halt tun.

58:17.540 --> 58:17.980
So.

58:18.720 --> 58:21.800
Und das Ausgabemodul kann jetzt halt über diesen letzten Index drüber

58:21.800 --> 58:25.460
gehen und den verschobenen Index, den Keyword in Context Index

58:25.460 --> 58:26.480
ausgeben.

58:26.920 --> 58:31.140
Das ist nicht so furchtbar dramatisch und denke ich auch einleuchtend.

58:31.980 --> 58:35.040
Der Treiber, wie gesagt, der sorgt dafür, dass das alles in der

58:35.040 --> 58:38.520
richtigen Reihenfolge aufgerufen wird und natürlich der Verschieber

58:38.520 --> 58:44.400
erst aufgerufen wird, wenn der Einleser fertig ist und der Sortierer

58:44.400 --> 58:46.560
erst läuft, wenn verschoben wurde.

58:47.520 --> 58:48.580
Eine große Magie.

58:49.200 --> 58:52.360
Wie die Schnittstellen aussehen, das schauen wir uns später an.

58:53.200 --> 58:54.260
Oder gar nicht.

58:55.000 --> 58:55.800
Mal schauen.

58:56.500 --> 58:58.920
Das würde funktionieren, das könnte man implementieren.

58:59.940 --> 59:03.380
Der Kommilitone sagt, es gibt jetzt hier diese Datenstruktur, nämlich

59:03.380 --> 59:07.340
diese Sortierung, die auf den Index zeigt und dieser Index zeigt

59:07.340 --> 59:08.260
wiederum auf den Speicher.

59:08.640 --> 59:13.420
Und wenn jetzt jemand den Verschiebeindex anders bauen will, dann muss

59:13.420 --> 59:16.320
ich auch diese Sortiergeschichte anders machen.

59:16.880 --> 59:20.720
Das heißt, ich habe eine Änderung, die eigentlich im Verschieber

59:20.720 --> 59:22.980
passiert, aber eine Auswirkung hat auf den Sortierer.

59:23.760 --> 59:24.800
Das ist ein Problem.

59:25.620 --> 59:27.140
Es gibt noch ein paar andere Probleme.

59:27.580 --> 59:29.820
Ich könnte mir nämlich überlegen, ich mache das nicht im RAM, sondern

59:29.820 --> 59:32.580
ich mache es auf der Platte oder ich mache das vielleicht gemischt

59:32.920 --> 59:36.200
oder ich mache nur die Hälfte, ich nehme eine andere Speichergröße,

59:37.260 --> 59:37.760
was auch immer.

59:37.880 --> 59:40.400
Ich packe das Ganze aus, weil ich habe jetzt plötzlich viel mehr

59:40.400 --> 59:40.820
Speicher.

59:42.380 --> 59:48.560
Es könnte vielleicht sogar sein, dass ich das gar nicht als ein

59:48.560 --> 59:51.780
Speicherbereich fortlaufend wegschreibe, sondern das irgendwie auf der

59:51.780 --> 59:52.500
Halde verteile.

59:52.980 --> 59:55.500
Es könnte sein, ich habe gar kein Problem mehr mit Speicher.

59:55.840 --> 59:59.680
Ich dupliziere das alles, weil was kostet schon Speicher heutzutage?

01:00:01.420 --> 01:00:04.520
Oder die Geschichte mit den Stoppwörtern, die haben wir nämlich noch

01:00:04.520 --> 01:00:05.300
gar nicht betrachtet.

01:00:05.920 --> 01:00:07.180
Die wollten wir auch noch überspringen.

01:00:08.140 --> 01:00:11.360
Egal, welche dieser Änderungen ich hernehme, ich muss immer alles

01:00:11.360 --> 01:00:14.860
ändern, außer dem Einleser und der Ausgabe am Ende.

01:00:15.420 --> 01:00:19.360
Und da gilt es natürlich auch nur, wenn die letzte Datenstruktur noch

01:00:19.360 --> 01:00:20.020
auflösbar ist.

01:00:20.340 --> 01:00:23.860
Das heißt, egal, was ich in dem Entwurf anpasse oder in der

01:00:23.860 --> 01:00:27.260
Implementierung anfasse, muss ich immer das gesamte Programm umgraben,

01:00:27.440 --> 01:00:28.880
und zwar mit einem sehr groben Spaten.

01:00:29.820 --> 01:00:31.680
Das ist natürlich nicht ganz so furchtbar gut.

01:00:32.900 --> 01:00:37.500
Das Einzige, was okay ist, ist, wenn man das Ausgabeformat ändert.

01:00:38.060 --> 01:00:40.820
Wenn ich das jetzt nicht mehr als LaTeX ausgebe, sondern als HTML,

01:00:41.480 --> 01:00:44.500
dann muss ich natürlich nur an dem Ausgabemodul arbeiten.

01:00:44.760 --> 01:00:46.920
Das hat ja keine Auswirkung auf die Speicherstrukturen.

01:00:47.480 --> 01:00:49.880
Aber alles andere, das wird echt teuer.

01:00:52.220 --> 01:00:53.160
Will man das haben?

01:00:53.740 --> 01:00:54.420
Natürlich nicht.

01:00:55.140 --> 01:00:56.400
Die Frage ist, wie kann man es besser machen?

01:00:57.600 --> 01:01:00.460
Sie erinnern sich, die Grafik von eben, die hatte ein paar Pfeile

01:01:00.460 --> 01:01:00.700
mehr.

01:01:02.180 --> 01:01:06.600
Und das ist ein Entwurf, mit dem man das deutlich besser machen kann.

01:01:06.820 --> 01:01:10.040
Und Sie sehen, oder Sie sollten sehen, dass es hier keine Zyklen gibt.

01:01:11.040 --> 01:01:12.220
Das ist schon mal ganz praktisch.

01:01:12.220 --> 01:01:17.120
Das heißt, der Treiber benutzt alle vier Module hier auf der Mitte.

01:01:17.240 --> 01:01:18.280
Das war vorher auch schon so.

01:01:18.740 --> 01:01:21.020
Die Ausgabe benutzt den Sortierer und den Verschieber.

01:01:21.120 --> 01:01:24.180
Der Sortierer benutzt nur den Verschieber und der Verschieber benutzt

01:01:24.180 --> 01:01:24.680
Eingabe.

01:01:26.120 --> 01:01:28.960
Der Verschieber benutzt den Zeilenspeicher und die Eingabe auch.

01:01:30.080 --> 01:01:31.460
Die muss es halt irgendwo hinspeichern.

01:01:33.200 --> 01:01:37.660
Aber, jetzt machen wir das Ganze schön mit einer Schnittstelle.

01:01:38.240 --> 01:01:40.280
Dann werden wir mal schauen, ob wir damit glücklicher sind.

01:01:41.360 --> 01:01:44.160
Kommt vielleicht ein bisschen umständlich daher, aber das löst

01:01:44.160 --> 01:01:44.620
einiges.

01:01:45.820 --> 01:01:48.080
Der Zeilenspeicher, wie implementieren wir den?

01:01:48.980 --> 01:01:53.740
Naja, wir gehen her und sagen, wir bauen eine Prozedur, mit der kann

01:01:53.740 --> 01:01:55.640
man einzelne Zeichen speichern.

01:01:56.260 --> 01:01:59.740
Und zwar mit vier Argumenten.

01:01:59.920 --> 01:02:07.800
Nämlich dem zurück, die Zeile, in der wir gerade sind, das entspricht

01:02:07.800 --> 01:02:08.380
dem Titel.

01:02:08.880 --> 01:02:10.780
Die muss man angeben als Parameter.

01:02:10.980 --> 01:02:13.880
Man muss das Wort angeben, und zwar den Index von dem Wort.

01:02:14.700 --> 01:02:15.240
Also das 0.

01:02:15.340 --> 01:02:15.860
Wort, das 1.

01:02:15.960 --> 01:02:16.540
Wort usw.

01:02:17.800 --> 01:02:21.460
Dann muss man angeben, wie viele Zeichen man schreibt.

01:02:22.160 --> 01:02:25.000
Und dann muss man natürlich angeben, was dahin geschrieben werden

01:02:25.000 --> 01:02:25.240
soll.

01:02:26.200 --> 01:02:29.180
Also eine relativ umständliche Methode, weil ich muss jetzt

01:02:29.180 --> 01:02:32.100
tatsächlich diesen Titel ja zeichenweise dahin speichern.

01:02:33.480 --> 01:02:33.660
Okay.

01:02:34.320 --> 01:02:37.200
Dann gibt es natürlich die umgekehrte Methode, mit der ich etwas holen

01:02:37.200 --> 01:02:37.420
kann.

01:02:37.680 --> 01:02:40.000
Das heißt, da fehlt einfach dieser d-Parameter.

01:02:40.620 --> 01:02:42.440
Dem kann ich einzelne Zeichen holen.

01:02:42.960 --> 01:02:46.480
Und ich kann mir auch die Gesamtzahl der Zeilen geben lassen.

01:02:47.780 --> 01:02:47.920
So.

01:02:48.220 --> 01:02:50.660
Das ist das, was dieser Zeilenspeicher macht.

01:02:51.780 --> 01:02:55.260
Was ich natürlich auch noch haben will, ist die Anzahl der Wörter in

01:02:55.260 --> 01:03:00.040
einer Zeile, in einem Titel, und die Anzahl der Zeichen in einem Wort.

01:03:00.820 --> 01:03:04.860
Damit habe ich jetzt quasi die Möglichkeit, abzufragen, wie viele

01:03:04.860 --> 01:03:06.600
Titel hat Hatz denn im Speicher?

01:03:07.080 --> 01:03:09.600
Und wenn ich einen rausgreife, wie viele Wörter hat der?

01:03:09.780 --> 01:03:12.080
Und wenn ich dann ein Wort rausgreife, kann ich sagen, wie viele

01:03:12.080 --> 01:03:13.500
Buchstaben hast du denn, Liebeswort?

01:03:14.200 --> 01:03:17.900
Und damit kann ich natürlich sehr einfach alles, was im Hauptspeicher

01:03:17.900 --> 01:03:20.160
steht, auch wieder auslesen.

01:03:21.320 --> 01:03:24.600
Sie können gerne als Übungsaufgabe das alles mal implementieren.

01:03:26.080 --> 01:03:27.700
Ich wünsche Ihnen viel Vergnügen dabei.

01:03:29.640 --> 01:03:33.080
Die nötigen Methoden sollten alle auf der Folie stehen.

01:03:33.940 --> 01:03:36.660
Aber wenn man das getan hat, dann kann man sich natürlich sehr einfach

01:03:36.660 --> 01:03:40.320
überlegen, mit drei Iterationen, also drei geschachtelten

01:03:40.320 --> 01:03:42.680
Vorschleifen, kann ich das gesamte Ding ausgeben wieder.

01:03:43.480 --> 01:03:46.340
Das heißt, ich iteriere zuerst mal über die Zeilen, das ist die

01:03:46.340 --> 01:03:49.840
äußerste, dann iteriere ich über die Wörter und dann iteriere ich über

01:03:49.840 --> 01:03:50.380
die Zeichen.

01:03:51.340 --> 01:03:53.520
Und dann droge ich einfach jedes Zeichen nacheinander aus.

01:03:53.660 --> 01:03:55.660
Und wenn ich fertig bin mit einem Wort, dann kommt ein

01:03:55.660 --> 01:03:57.320
Leerzeilzeichen.

01:03:58.140 --> 01:04:04.940
Und wenn ich mit der Zeile fertig bin, dann kommt a new line.

01:04:06.440 --> 01:04:08.360
Und damit kann ich das alles wieder ausdrucken.

01:04:08.640 --> 01:04:11.520
Das heißt, offensichtlich ist die Schnittstelle dazu geeignet, die

01:04:11.520 --> 01:04:15.780
ganzen Wörter, die ganzen Titel im Hauptspeicher abzulegen oder sonst

01:04:15.780 --> 01:04:15.980
wo.

01:04:16.960 --> 01:04:18.340
Und sie auch da wieder rauszuholen.

01:04:19.240 --> 01:04:21.400
Und mehr braucht man eigentlich nicht, um das ganze Zeug zu

01:04:21.400 --> 01:04:23.000
implementieren, was wir gerade gesehen haben.

01:04:24.260 --> 01:04:25.800
Was wir brauchen, ist ein Verschieber.

01:04:26.520 --> 01:04:30.100
Der muss eben die ganzen Verschiebungen hinbringen.

01:04:30.840 --> 01:04:34.360
Das heißt, er muss uns sagen, wie viele Verschiebungen gibt es denn

01:04:34.360 --> 01:04:34.720
überhaupt?

01:04:35.820 --> 01:04:40.600
Und er hat eine Zugriffsmethode, die sich auf die Verschiebung

01:04:40.600 --> 01:04:40.980
bezieht.

01:04:41.060 --> 01:04:45.660
Das ist im Grunde dieselbe Methode, wie direkt für den Titel, nur eben

01:04:45.660 --> 01:04:46.860
für die 0.1.

01:04:47.080 --> 01:04:48.280
und so weiter Verschiebung.

01:04:51.040 --> 01:04:54.040
Natürlich kann ich auch noch die Wörter holen von der Verschiebung und

01:04:54.040 --> 01:04:56.740
die Buchstaben eines Wortes.

01:04:59.420 --> 01:05:03.140
Das ist also genau das Gleiche beim Zeilenspeicher vorhin, nur eben

01:05:03.140 --> 01:05:03.860
mit den Verschiebungen.

01:05:05.680 --> 01:05:08.800
Der Verschieber, der kann jetzt intern einen Index erzeugen, so wie

01:05:08.800 --> 01:05:10.260
das im ersten Entwurf der Fall war.

01:05:10.780 --> 01:05:15.300
Der kann das Ganze bei Bedarf berechnen, kann man ja auch machen.

01:05:16.220 --> 01:05:20.800
Der könnte die Verschiebung tatsächlich explizit speichern, wenn

01:05:20.800 --> 01:05:21.640
Speicher da ist.

01:05:22.420 --> 01:05:25.760
Und egal, wie sie sich hier entscheiden, die Schnittstelle wird sich

01:05:25.760 --> 01:05:26.200
nicht ändern.

01:05:26.560 --> 01:05:29.620
Der Zugriff auf die Verschiebung ist immer der gleiche.

01:05:31.060 --> 01:05:33.060
Der Sortierer, der funktioniert genauso.

01:05:34.520 --> 01:05:41.420
Sie machen eine Methode, Alphabetisierer heißt, wer auch immer das

01:05:41.420 --> 01:05:42.080
übersetzt hat.

01:05:43.600 --> 01:05:46.580
Der sorgt dafür, dass dieser verschobene Index sortiert wird.

01:05:47.560 --> 01:05:50.660
Und natürlich könnte man das auch nach und nach berechnen, nur wenn

01:05:50.660 --> 01:05:51.260
man es braucht.

01:05:51.400 --> 01:05:54.960
Oder man könnte zuerst mal nur nach dem ersten Buchstaben sortieren

01:05:54.960 --> 01:05:55.980
und dann hätte man Blöcke.

01:05:57.440 --> 01:05:59.440
Innerhalb von diesen Blöcken ist dann noch nichts sortiert.

01:06:00.100 --> 01:06:01.500
Könnte man nachholen oder auch nicht.

01:06:02.280 --> 01:06:06.260
All diese Entscheidungen können Sie treffen und auch wieder

01:06:06.260 --> 01:06:06.760
revidieren.

01:06:07.680 --> 01:06:09.300
Ändert sich an der Schnittstelle gar nichts.

01:06:11.460 --> 01:06:12.880
Die Eingabe ist natürlich klar.

01:06:13.020 --> 01:06:15.880
Es gibt eine Prozedur Einlesen, die macht halt die Datei auf und

01:06:15.880 --> 01:06:19.180
benutzt den Zeilenspeicher, um das Ganze in den Speicher zu schieben.

01:06:19.620 --> 01:06:23.760
Und es gibt eine Ausgabe, die alle Verschiebungen abfrägt und

01:06:23.760 --> 01:06:24.920
ausdruckt.

01:06:26.380 --> 01:06:31.080
Nicht so furchtbar viel Magie, aber ein bisschen einfacher.

01:06:33.020 --> 01:06:35.600
Hat jemand eine Frage zu dem Quick Index bis hierhin?

01:06:36.440 --> 01:06:38.800
Außer vielleicht braucht man das heute noch.

01:06:43.450 --> 01:06:44.130
Okay.

01:06:45.990 --> 01:06:50.070
Ein anderes Beispiel für so eine Kapselung.

01:06:51.130 --> 01:06:53.090
Die AWT-Klasse Component.

01:06:54.650 --> 01:06:58.090
Und das ist was, was Sie brauchen, um grafische Benutzeroberflächen zu

01:06:58.090 --> 01:06:59.890
bauen, wenn Sie den AWT benutzen.

01:07:01.230 --> 01:07:06.810
Sie können die einfach benutzen, ohne sich Gedanken drüber zu machen,

01:07:06.910 --> 01:07:09.670
wie das Ding intern die Einzelkomponenten abspeichert.

01:07:10.430 --> 01:07:14.170
Eine Komponente in der grafischen Oberfläche ist geschachtelt.

01:07:14.290 --> 01:07:17.730
Sie haben ganz außen ein Fenster und innerhalb von diesem Fenster gibt

01:07:17.730 --> 01:07:19.150
es was, wo Sie darauf zeichnen können.

01:07:19.350 --> 01:07:23.190
Da gibt es vielleicht einen oberen, einen unteren Bereich und im

01:07:23.190 --> 01:07:26.510
oberen Bereich haben Sie eine Schaltfläche und so weiter.

01:07:26.970 --> 01:07:29.590
Und das ist nichts anderes als eine geschachtelte Hierarchie von

01:07:29.590 --> 01:07:33.030
Elementen und wie diese Elemente gespeichert werden, das kann Ihnen

01:07:33.030 --> 01:07:33.570
egal sein.

01:07:33.770 --> 01:07:36.370
Sie können einfach die Komponente fragen, gib mir mal alles, was in

01:07:36.370 --> 01:07:36.890
dir drin ist.

01:07:37.470 --> 01:07:38.750
Oder leg noch was dazu.

01:07:39.710 --> 01:07:40.470
Kein Problem.

01:07:41.710 --> 01:07:46.450
Und das ist sehr einfach, über diese Einzelkomponenten zu iterieren,

01:07:46.530 --> 01:07:48.450
weil Sie können natürlich fragen, wie viele sind da drin.

01:07:49.590 --> 01:07:52.630
Gib mir mal alle oder gib mir eine Liste oder gib mir das fünfte.

01:07:53.610 --> 01:07:56.210
Das können Sie alles machen, ohne zu wissen, wie das intern abgelegt

01:07:56.210 --> 01:07:56.450
ist.

01:07:58.170 --> 01:08:00.790
Vielleicht ist es sogar nur implizit gespeichert, weil die tatsächlich

01:08:00.790 --> 01:08:05.650
geschachtelt sind und jede innere Instanz einen Zeiger hat, auf die

01:08:05.650 --> 01:08:10.170
direkt äußere, also quasi jede Schicht nur einen Zeiger nach oben hat.

01:08:10.870 --> 01:08:11.710
Könnte auch sein.

01:08:13.050 --> 01:08:15.970
Müssen Sie aber gar nicht wissen, weil die Zugriffsmethoden von dem

01:08:15.970 --> 01:08:18.250
Component das alles für Sie machen.

01:08:19.570 --> 01:08:20.030
Sehr hübsch.

01:08:20.670 --> 01:08:21.490
Sieht dann so aus.

01:08:22.230 --> 01:08:25.850
Sie können Komponenten hinzufügen, Sie können sogar sagen, an welche

01:08:25.850 --> 01:08:29.190
Position das hinzugefügt werden soll, wenn Sie da Einfluss nehmen

01:08:29.190 --> 01:08:29.450
wollen.

01:08:30.030 --> 01:08:33.050
Und es gibt Methoden, um das Zeug wieder rauszuholen und

01:08:33.050 --> 01:08:33.670
rauszulöschen.

01:08:34.470 --> 01:08:38.530
Wie das implementiert ist, ist uns egal.

01:08:39.330 --> 01:08:40.270
Das kann sich auch ändern.

01:08:41.170 --> 01:08:42.270
Sollte uns nicht stören.

01:08:42.750 --> 01:08:47.790
Insbesondere hat der Container, der die Komponente beerbt, er hat

01:08:47.790 --> 01:08:53.870
keinerlei öffentliche Methoden, öffentliche Attribute, über die Sie

01:08:53.870 --> 01:08:55.870
quasi an die Kernkomponenten rankommen können.

01:08:56.830 --> 01:08:58.790
Sie sollen immer diese Zugriffsmethoden benutzen.

01:09:00.210 --> 01:09:01.750
Wie gesagt, entfernen können Sie auch noch.

01:09:03.470 --> 01:09:03.990
Zur Übung.

01:09:03.990 --> 01:09:08.950
Nehmen Sie mal einen Iterator, der das Ding tatsächlich in der

01:09:08.950 --> 01:09:10.770
richtigen Reihenfolge ausguckt.

01:09:11.330 --> 01:09:14.830
Zwar ohne dieses Array sich rausgeben zu lassen.

01:09:16.790 --> 01:09:18.490
Das sollte eine Fingerübung sein.

01:09:18.910 --> 01:09:19.970
Und wenn es das ist, dann ist gut.

01:09:20.070 --> 01:09:21.850
Wenn nicht, gucken Sie nochmal nach, wie das funktioniert.

01:09:24.610 --> 01:09:28.590
Jetzt wollen wir die Module, die wir haben, die wir beschrieben haben

01:09:28.590 --> 01:09:32.250
und deren Ein- und Ausgabeschnittstellen wir beschrieben haben,

01:09:32.330 --> 01:09:33.290
irgendwie speichern.

01:09:33.990 --> 01:09:36.950
Am besten in Programmcode, weil nur dann kann man es benutzen.

01:09:38.150 --> 01:09:42.610
Und in vielen Programmiersprachen gibt es einfach sprachliche Mittel,

01:09:42.710 --> 01:09:43.270
um das zu tun.

01:09:43.850 --> 01:09:47.850
Und da wir hier beim Modul sind, werden wir uns C anschauen, oder C++,

01:09:48.110 --> 01:09:48.690
ich weiß nicht genau.

01:09:50.670 --> 01:09:56.110
Und naja, das ist sehr ähnlich dem, was Sie hinterher in Java auch

01:09:56.110 --> 01:09:57.830
sehen, im objektorientierten Umfeld.

01:09:59.190 --> 01:10:02.650
Aber, wer von Ihnen kann C so richtig?

01:10:03.470 --> 01:10:05.590
Wow, wer mag vorkommen und das erklären?

01:10:08.070 --> 01:10:08.630
Okay.

01:10:10.170 --> 01:10:16.530
Gut, also in C oder C++ funktioniert das so, dass Sie für jedes Modul

01:10:16.530 --> 01:10:20.590
zwei Dateien haben, eine Header-Datei und eine Implementierungsdatei.

01:10:21.130 --> 01:10:24.990
Und die Header-Datei speichert man in der Regel unter Punkt H und die

01:10:24.990 --> 01:10:29.190
Implementierungsdatei unter Punkt C oder C++ oder wie auch immer Sie

01:10:29.190 --> 01:10:29.790
das haben mögen.

01:10:30.830 --> 01:10:36.470
Und in der Header-Datei, da steht die Modul-Schnittstelle drin und

01:10:36.470 --> 01:10:37.050
nichts anderes.

01:10:38.410 --> 01:10:42.490
Und jeder, der dieses Modul benutzen möchte, der braucht diese Header

01:10:42.490 --> 01:10:42.950
-Datei.

01:10:43.410 --> 01:10:43.870
Der liest die.

01:10:45.110 --> 01:10:48.390
Insbesondere liest die auch die Implementierung, weil die muss ja

01:10:48.390 --> 01:10:50.090
wissen, was sie da eigentlich implementieren soll.

01:10:51.370 --> 01:10:54.710
Was es aber nicht gibt, ist eine Überprüfung der Namenskonvention.

01:10:54.710 --> 01:10:59.730
Das heißt, Sie können die eine, die Header-Datei U nennen und die

01:10:59.730 --> 01:11:01.250
Implementierungs -Datei Bar.

01:11:02.410 --> 01:11:05.030
Solange Sie innen drin alles richtig machen, wird das funktionieren.

01:11:06.250 --> 01:11:07.770
Aber ich empfehle es Ihnen nicht.

01:11:08.010 --> 01:11:11.730
Gucken Sie drauf, dass die Punkt H und Punkt C-Dateien den gleichen

01:11:11.730 --> 01:11:13.610
Namen haben, wenn sie zum selben Modul gehören.

01:11:16.050 --> 01:11:18.790
Wie sieht es jetzt also aus im Zeilenspeicher?

01:11:19.350 --> 01:11:22.550
Da haben wir uns ja überlegt, da gibt es diese unsägliche Methode mit

01:11:22.550 --> 01:11:28.410
den vier Argumenten, nämlich mit der Zeile, dem Wort, dem Zeichen und

01:11:28.410 --> 01:11:30.330
dem Wert, der gespeichert werden soll.

01:11:31.070 --> 01:11:33.250
Und das ist dann auch genau die Definition hier.

01:11:33.490 --> 01:11:35.770
Also Void ist der Rückgabetyp, genauso wie in Java.

01:11:36.610 --> 01:11:39.530
Letzte Zeichen ist der Methodenname und dann kommt eine Liste mit den

01:11:39.530 --> 01:11:40.550
Argumenten.

01:11:41.330 --> 01:11:43.590
Und das gibt es für alle Methoden, die dieses Modul hat.

01:11:44.030 --> 01:11:45.390
Steht da einfach hintereinander weg.

01:11:47.390 --> 01:11:49.830
Und der Verschieber, der funktioniert genauso.

01:11:50.110 --> 01:11:53.830
Da sind jetzt einfach alle Methoden hingeschrieben, die vorher im

01:11:53.830 --> 01:11:56.210
Fließtext auf den Folien standen.

01:11:56.330 --> 01:11:57.790
Nur eben jetzt hier als Deklaration.

01:11:59.970 --> 01:12:04.230
Und dann müssen die Module sich ja gegenseitig benutzen.

01:12:05.190 --> 01:12:07.670
Und das erste Modul, das war der Zeilenspeicher.

01:12:08.290 --> 01:12:13.850
Wie gesagt, die .h-Datei, der Header, das ist hier immer mit

01:12:15.350 --> 01:12:16.430
dunkelblau dargestellt.

01:12:17.450 --> 01:12:21.310
Die wird importiert in die Implementierung von dem Zeilenspeicher.

01:12:21.930 --> 01:12:25.010
Der muss wissen, wie ist die Schnittstelle, die ich implementiere.

01:12:25.990 --> 01:12:27.830
Und dann gibt es das Gleiche noch für die Eingabe.

01:12:28.390 --> 01:12:32.510
Und die Eingabe, die Implementierung der Eingabe, die muss ja den

01:12:32.510 --> 01:12:33.670
Zeilenspeicher benutzen.

01:12:34.530 --> 01:12:38.010
Deswegen importiert sie auch die Schnittstelle vom Zeilenspeicher.

01:12:38.590 --> 01:12:42.710
Das heißt, in dieser grünen Implementierungsdatei für die Eingabe

01:12:42.710 --> 01:12:44.310
stehen zwei Includes drin.

01:12:44.770 --> 01:12:46.890
Nämlich für den Zeilenspeicher und für die Eingabe.

01:12:48.650 --> 01:12:50.670
Und das Ganze geht dann schön weiter.

01:12:52.730 --> 01:12:53.470
Das ist der letzte.

01:12:54.450 --> 01:12:57.010
Im Hauptprogramm, da werden natürlich einfach alle benutzt.

01:12:57.490 --> 01:13:00.610
Nur, dass das Hauptprogramm wahrscheinlich nicht wissen muss, wie der

01:13:00.610 --> 01:13:01.710
Zeilenspeicher funktioniert.

01:13:02.950 --> 01:13:04.810
Weil darauf greift das Hauptprogramm ja nie zu.

01:13:06.270 --> 01:13:07.110
Das ist ja ganz nett.

01:13:07.110 --> 01:13:07.870
So.

01:13:11.330 --> 01:13:11.930
Genau.

01:13:13.370 --> 01:13:13.650
Gut.

01:13:14.630 --> 01:13:18.570
Der Unterschied zwischen einem Modul und dem, was Sie als Klasse

01:13:18.570 --> 01:13:21.370
kennengelernt haben, ist relativ elementar.

01:13:22.090 --> 01:13:23.710
So ein Modul haben Sie genau einmal.

01:13:24.810 --> 01:13:27.330
Bei einer Klasse können Sie beliebig viele Instanzen anlegen.

01:13:27.890 --> 01:13:28.970
Ein Modul haben Sie einmal.

01:13:29.510 --> 01:13:33.930
Wenn Sie dasselbe Modul zweimal haben wollen, dann müssen Sie dem

01:13:33.930 --> 01:13:36.210
einen anderen Namen geben und es nebendran legen.

01:13:37.170 --> 01:13:39.150
Und dann viel Spaß beim Warten.

01:13:39.850 --> 01:13:41.430
Dann müssen Sie nämlich immer doppelt warten.

01:13:42.030 --> 01:13:45.350
Das ist ein bisschen ungeschickt, aber so ist das halt.

01:13:47.930 --> 01:13:49.270
Und was haben wir noch?

01:13:50.750 --> 01:13:54.090
Mal gucken, dass ich hier nicht Quatsch erzähle.

01:13:59.240 --> 01:13:59.440
Genau.

01:14:05.450 --> 01:14:05.950
Ja.

01:14:06.710 --> 01:14:08.230
Genau, das hatte ich Ihnen alles gesagt.

01:14:09.010 --> 01:14:11.870
Die Schnittstellen sind vordefiniert und wenn Sie das Modul einmal

01:14:11.870 --> 01:14:13.990
haben, dann haben Sie es und zwar einmal.

01:14:14.610 --> 01:14:17.850
Wenn Sie es noch ein zweites Mal haben wollen, dann müssen Sie das

01:14:17.850 --> 01:14:19.190
eben anders lösen.

01:14:21.010 --> 01:14:24.450
Das kriegen Sie durch Mehrfachinstanzierung hin in Java.

01:14:24.810 --> 01:14:25.790
Das ist überhaupt kein Thema.

01:14:27.490 --> 01:14:32.610
Und wenn Sie wollen, dass eine Schnittstelle unterschiedlich

01:14:32.610 --> 01:14:35.450
implementiert wird, naja, dann legen Sie halt zwei Klassen an und die

01:14:35.450 --> 01:14:37.070
implementieren beide dieselbe Schnittstelle.

01:14:37.570 --> 01:14:37.970
Wunderbar.

01:14:39.010 --> 01:14:44.910
Wenn Sie an diese Header-Dateien denken, wenn Sie wollen, dass es

01:14:44.910 --> 01:14:47.350
einen anderen Zeilenspeicher gibt, der die gleiche Schnittstelle

01:14:47.350 --> 01:14:50.270
implementiert, dann können Sie natürlich hier eine andere

01:14:50.270 --> 01:14:55.210
Zeilenspeicher -Implementierung anlegen und darin diese Schnittstelle

01:14:55.210 --> 01:14:56.450
hier oben inkludieren.

01:14:57.350 --> 01:15:00.370
Dann haben Sie im Prinzip das Gleiche erreicht, aber Sie haben dann

01:15:00.370 --> 01:15:03.270
eine Header-Datei für zwei C-Dateien und das ist ein bisschen

01:15:03.270 --> 01:15:03.910
hässlich.

01:15:04.650 --> 01:15:07.650
Also Sie würden da tatsächlich eine Kopie anlegen und hoffen, dass

01:15:07.650 --> 01:15:08.450
sich das nicht ändert.

01:15:09.190 --> 01:15:13.070
Oder in einem Kommentar hinschreiben, dass man beides mit pflegen

01:15:13.070 --> 01:15:13.370
muss.

01:15:17.410 --> 01:15:21.590
Sie können relativ schwer Bezeichner mehrfach verwenden.

01:15:22.250 --> 01:15:23.190
Das ist einfach schwierig.

01:15:23.530 --> 01:15:28.570
Wenn Sie Dateinamen wählen und da ist genauso wie das Modul, naja,

01:15:28.650 --> 01:15:31.890
dann können Sie einfach im selben Verzeichnis nicht noch mal eine

01:15:31.890 --> 01:15:33.810
andere Datei mit dem selben Namen anlegen.

01:15:34.570 --> 01:15:36.010
Das ist ein bisschen doof.

01:15:36.670 --> 01:15:38.010
Und wir haben das auch gesehen hier.

01:15:38.590 --> 01:15:41.990
Wir haben einmal HOLE-Zeichen, das war einfach nur für den

01:15:41.990 --> 01:15:42.670
Zeilenspeicher.

01:15:43.070 --> 01:15:46.650
Und wir haben VS HOLE-Zeichen, das war das mit den Verschiebungen.

01:15:47.450 --> 01:15:51.470
Und naja, wenn Sie an Java denken, Sie hätten natürlich einmal

01:15:51.470 --> 01:15:53.290
Zeilenspeicher.HOLE-Zeichen.

01:15:53.870 --> 01:15:57.570
Einmal hätten Sie eine Klasse Verschieber.HOLE-Zeichen angelegt.

01:15:57.970 --> 01:16:01.550
Und nicht Verschieber.VS HOLE-Zeichen.

01:16:01.550 --> 01:16:03.130
Das ist halt so.

01:16:03.830 --> 01:16:07.030
Und Sie können vielleicht glücklich sein, dass Sie in Java unterwegs

01:16:07.030 --> 01:16:07.350
sind.

01:16:07.930 --> 01:16:11.710
Die vielen, die sich bei Ich kann C gemeldet haben, die sind

01:16:11.710 --> 01:16:14.010
vielleicht traurig darüber, dass sie hier nicht C machen dürfen.

01:16:14.750 --> 01:16:18.370
Aber naja, wir müssen uns auf einen gemeinsamen Nenner einigen.

01:16:19.410 --> 01:16:20.350
Hier in der Vorlesung.

01:16:21.910 --> 01:16:22.150
Gut.

01:16:24.330 --> 01:16:27.290
Die Benutzrelationen, die kann man auf verschiedene Arten

01:16:27.290 --> 01:16:27.770
hinschreiben.

01:16:28.610 --> 01:16:32.770
Offensichtlich gibt es die Benutzt-Kante, die Uses-Kante.

01:16:33.450 --> 01:16:37.090
Sie können aber natürlich auch noch aufschreiben, wer ruft wen auf,

01:16:37.270 --> 01:16:39.170
wer wird aufgerufen von wem anderen.

01:16:41.030 --> 01:16:45.270
Wer besitzt irgendwas, wer enthält irgendwas, wenn Sie geschachtelte

01:16:45.270 --> 01:16:45.930
Module haben.

01:16:46.670 --> 01:16:52.170
Wir erinnern uns, Module und Systeme und Subsysteme.

01:16:52.250 --> 01:16:54.350
Dann können Sie das natürlich da auch aufmalen.

01:16:56.250 --> 01:16:58.730
Ist aber, denke ich, an sich nicht so furchtbar spannend.

01:17:00.010 --> 01:17:00.110
Oder?

01:17:02.490 --> 01:17:03.130
Okay.

01:17:04.030 --> 01:17:04.310
Gut.

01:17:06.150 --> 01:17:08.810
Die Benutzrelationen, die brauchen wir noch als Definition.

01:17:10.110 --> 01:17:16.750
Und zwar lautet die, eine Programmkomponente A benutzt eine andere

01:17:17.310 --> 01:17:21.490
Programmkomponente B genau dann, wenn A für den korrekten Ablauf die

01:17:21.490 --> 01:17:24.790
Verfügbarkeit einer korrekten Implementierung von B erfordert.

01:17:24.790 --> 01:17:27.150
Also A hängt ab von B.

01:17:28.910 --> 01:17:34.930
Und wenn Sie sich das überlegen, A könnte Arbeit an B delegieren.

01:17:35.210 --> 01:17:37.710
Es könnte sein, dass A irgendwas braucht, was B halt kann.

01:17:38.670 --> 01:17:41.730
Könnte aber auch sein, dass A auf irgendwelche Variablen zugreift in

01:17:41.730 --> 01:17:41.950
B.

01:17:43.010 --> 01:17:47.870
Es könnte sein, dass einfach ein Aufruf passiert.

01:17:48.250 --> 01:17:50.770
Oder, dass Sie eine Instanz anlegen von dem anderen Typ.

01:17:52.030 --> 01:17:55.850
Das sind alles Dinge, bei denen Sie sicherstellen müssen, dass B

01:17:55.850 --> 01:17:58.990
richtig funktioniert, damit das, was A tun soll, auch funktionieren

01:17:58.990 --> 01:17:59.230
kann.

01:18:00.350 --> 01:18:01.670
Nicht so furchtbar überraschend.

01:18:01.750 --> 01:18:03.430
Wenn ich was benutze, dann soll es funktionieren.

01:18:05.810 --> 01:18:09.110
Und naja, da gibt es verschiedene Möglichkeiten.

01:18:09.390 --> 01:18:11.710
Sie können eine Halbordnung bauen, Sie können eine Totalordnung bauen

01:18:11.710 --> 01:18:13.250
und Sie können natürlich auch einen Zyklus bauen.

01:18:14.250 --> 01:18:15.350
Zyklus machen Sie bitte nicht.

01:18:15.770 --> 01:18:16.830
Das ist eine ganz blöde Idee.

01:18:19.110 --> 01:18:23.530
Beispiele, die Sie wahrscheinlich kennen, ist die ISO-OSI-Protokoll

01:18:23.530 --> 01:18:25.390
-Suite oder die TCP-IP-Suite.

01:18:26.430 --> 01:18:29.690
Da haben Sie ganz klar eine Benutzrelation von oben nach unten.

01:18:30.350 --> 01:18:34.850
Also TCP, das Protokoll benutzt IP und IP benutzt, ich weiß nicht was.

01:18:36.090 --> 01:18:38.230
Falls Sie schon Telematik hatten, haben Sie es da gelernt.

01:18:38.330 --> 01:18:39.630
Für mich dürfen Sie es dort lernen.

01:18:41.710 --> 01:18:44.770
Das Gleiche kennt man natürlich auch bei einer Schichtenarchitektur.

01:18:44.910 --> 01:18:48.090
Das heißt, Sie haben ganz unten die Datenhaltung.

01:18:48.390 --> 01:18:51.850
Da liegt die Datenbank oder die Datei oder das Bandlaufwerk, was auch

01:18:51.850 --> 01:18:52.050
immer.

01:18:52.670 --> 01:18:54.230
Dann kommt der Applikationskern.

01:18:54.590 --> 01:18:56.470
Der greift auf die Datenhaltung zu.

01:18:57.150 --> 01:18:59.390
Und ganz oben haben Sie die Benutzungsschnittstelle.

01:18:59.530 --> 01:19:03.090
Ob das jetzt eine grafische Oberfläche ist oder eine Textkonsole, das

01:19:03.090 --> 01:19:03.850
ist völlig egal.

01:19:04.270 --> 01:19:07.950
Wichtig ist, die Benutzungsschnittstelle, die greift nicht auf die

01:19:07.950 --> 01:19:12.190
Datenhaltung zu, sondern die greift auf den Applikationskern zu.

01:19:12.310 --> 01:19:15.650
Und wenn Sie was aus der Datenhaltung haben will, dann soll Sie bitte

01:19:15.650 --> 01:19:17.410
den Applikationskern danach fragen.

01:19:18.570 --> 01:19:21.570
Ansonsten haben Sie einfach das Problem, wenn Sie die Datenhaltung

01:19:21.570 --> 01:19:23.770
ändern, müssen Sie alles ändern, was hinten rankommt.

01:19:24.370 --> 01:19:25.110
Das wollen Sie ja nicht.

01:19:25.530 --> 01:19:28.510
Sie wollen dann nur im Applikationskern die Anpassung nachziehen.

01:19:34.650 --> 01:19:35.510
Zwei Minuten.

01:19:35.690 --> 01:19:36.370
Das ist noch ganz schön lange.

01:19:38.590 --> 01:19:42.290
A soll B nur dann benutzen, wenn alle Kriterien zutreffen, die auf

01:19:42.290 --> 01:19:43.010
dieser Folie stehen.

01:19:43.570 --> 01:19:47.750
Das heißt, A wird durch die Benutzung von B einfacher.

01:19:48.630 --> 01:19:50.630
Das System wird besser verstehbar.

01:19:51.910 --> 01:19:52.870
Das ist ein wichtiger Punkt.

01:19:53.290 --> 01:19:56.990
Wenn das einfach nur komplizierter wird und Sie es machen, damit Sie

01:19:56.990 --> 01:20:00.230
irgendwas benutzen, dann vielleicht nochmal über den Entwurf

01:20:00.230 --> 01:20:02.050
nachdenken.

01:20:04.030 --> 01:20:07.410
Auch ein Punkt ist, jetzt haben wir uns A angeschaut, was passiert

01:20:07.410 --> 01:20:07.910
denn mit B?

01:20:08.570 --> 01:20:12.110
Wenn B benutzt werden soll von A, dann muss es ja was bereitstellen.

01:20:12.110 --> 01:20:15.810
Und wenn es das nicht ohnehin schon tut, dann muss man dieses B größer

01:20:15.810 --> 01:20:18.310
machen, erweitern, die Schnittstelle aufbohren, was auch immer.

01:20:18.850 --> 01:20:22.650
Und das sollten Sie nur dann tun, wenn B dadurch nicht wesentlich

01:20:22.650 --> 01:20:23.450
komplexer wird.

01:20:24.570 --> 01:20:27.730
Sie sollen am besten die Einfachheit hochhalten, und zwar auf beiden

01:20:27.730 --> 01:20:28.050
Seiten.

01:20:30.310 --> 01:20:36.010
Es ist relativ wichtig, dass Sie nicht einfach so Module bauen, damit

01:20:36.010 --> 01:20:37.130
Sie Module gebaut haben.

01:20:37.310 --> 01:20:41.790
Wenn es niemals einen Fall gibt, wo B alleine von irgendwas anderem

01:20:41.790 --> 01:20:45.530
benutzt wird, sondern es wird immer nur von A benutzt, und es ist nur

01:20:45.530 --> 01:20:48.790
sehr klein, warum haben Sie dann überhaupt zwei Module gemacht?

01:20:49.830 --> 01:20:53.070
Das ist dann vielleicht zu feindgliedrig gemacht.

01:20:55.550 --> 01:20:57.050
Müssen Sie sich einfach überlegen.

01:20:57.750 --> 01:21:01.750
Es könnte auch eine Überlegung sein, dass Sie sagen, naja, das ist

01:21:01.750 --> 01:21:03.290
jetzt vielleicht...

01:21:03.290 --> 01:21:08.090
A ist im Moment der einzige Klient von B, aber ich weiß, da kommt noch

01:21:08.090 --> 01:21:10.550
viel mehr dazu, und zwar schon nächste Woche.

01:21:10.850 --> 01:21:13.350
Dann ist es vielleicht trotzdem sinnvoll, das schon auszugliedern.

01:21:14.350 --> 01:21:17.370
Sie müssen also bei dieser Entwurfsentscheidung auch berücksichtigen,

01:21:17.450 --> 01:21:19.050
was vielleicht nächste Woche noch passiert.

01:21:19.670 --> 01:21:22.270
Wir müssen ein bisschen hell sehen, auch wenn das vielleicht

01:21:22.270 --> 01:21:22.770
schwerfällt.

01:21:24.850 --> 01:21:26.570
Jetzt kommt das mit der Benutz-Hierarchie.

01:21:26.670 --> 01:21:28.250
Das hatte ich schon ganz am Anfang mal gesagt.

01:21:28.710 --> 01:21:34.150
Wenn die Hierarchie, die Benutz-Relation zyklenfrei ist, dann heißt

01:21:34.150 --> 01:21:36.430
sie Hierarchie, und das ist genau das, was Sie haben wollen.

01:21:37.390 --> 01:21:40.030
Wenn Sie einen Zyklus drin haben, dann müssen Sie alle am Zyklus

01:21:40.030 --> 01:21:43.150
beteiligten Komponenten gleichzeitig fertig haben.

01:21:43.750 --> 01:21:46.910
Und Sie können vorher nicht testen, ob das funktioniert, weil dafür

01:21:46.910 --> 01:21:49.490
müsste der Rest schon fertig sein, und damit der Rest fertig ist,

01:21:50.110 --> 01:21:51.890
dafür müssten Sie schon fertig gewesen sein.

01:21:52.930 --> 01:21:54.450
Da beißt sich die Katze dann entspannt.

01:21:55.130 --> 01:21:57.550
Deswegen versuchen Sie eine Hierarchie hinzukriegen, wenn Sie es

01:21:57.550 --> 01:21:57.770
schaffen.

01:21:59.050 --> 01:22:05.270
Und hier haben Sie so einen Punkt, das heißt A benutzt C, C benutzt F,

01:22:06.210 --> 01:22:09.330
und das geht hier wieder nach oben, das heißt mit dieser blauen Kante,

01:22:09.410 --> 01:22:12.270
die hier durchgestrichen ist, da hätten Sie genau einen Zyklus, und

01:22:12.270 --> 01:22:14.630
Sie kriegen es einfach nicht hin, dieses System zum Fliegen zu

01:22:14.630 --> 01:22:17.130
kriegen, bis Sie eben alles erledigt haben.

01:22:17.750 --> 01:22:21.550
Das ist sehr schlecht für die inkrementelle Entwicklung, das ist sehr

01:22:21.550 --> 01:22:24.130
schlecht für die eigenständige Verwendung von diesen einzelnen

01:22:24.130 --> 01:22:29.070
Modulen, weil die hängen ja von allem ab, und Sie kriegen es auch

01:22:29.070 --> 01:22:30.770
nicht hin, da Teillieferungen zu machen.

01:22:30.910 --> 01:22:34.650
Stellen Sie sich vor, Sie haben ein Projekt und Sie könnten zu Ihrem

01:22:34.650 --> 01:22:40.730
Kunden sagen, okay, ich mache mal die Komponenten A, B, C fertig und

01:22:40.730 --> 01:22:42.990
nächste Woche liefere ich dann den Rest, aber ich hätte gern schon mal

01:22:42.990 --> 01:22:43.990
die Hälfte des Geldes.

01:22:44.690 --> 01:22:47.390
Dann sagt er vielleicht, ja ist okay, aber wenn Sie ihm dann sagen,

01:22:47.510 --> 01:22:50.670
aber du kannst es gar nicht benutzen, weil das geht erst, wenn du

01:22:50.670 --> 01:22:54.290
alles hast, dann wird er sagen, ja gut, dann kriegst du auch erst

01:22:54.290 --> 01:22:55.510
Geld, wenn alles fertig ist.

01:22:56.610 --> 01:22:59.650
Also es gibt viele Gründe, warum Sie da keine Zyklen drin haben

01:22:59.650 --> 01:22:59.930
wollen.

01:23:02.950 --> 01:23:08.830
Was man machen kann, sind Callbacks, das heißt der Anwendungskern, der

01:23:08.830 --> 01:23:11.450
ist hier eigentlich die untere Schicht, die Benutzerschnittstelle

01:23:13.170 --> 01:23:17.690
verwendet die untere Schicht, den Anwendungskern, aber es gibt Dinge,

01:23:17.830 --> 01:23:19.870
die löst der Anwendungskern auf der GUI aus.

01:23:20.790 --> 01:23:22.110
Das passiert natürlich jeden Tag.

01:23:22.790 --> 01:23:26.490
Und dann macht man Callbacks, das heißt da haben Sie eine lose

01:23:26.490 --> 01:23:28.090
Kopplung, aber keine Abhängigkeit.

01:23:28.570 --> 01:23:31.730
Das funktioniert so, dass sich die GUI am Anwendungskern registriert

01:23:31.730 --> 01:23:34.470
und nur wenn das passiert ist, dann kommt überhaupt ein Rückruf.

01:23:34.930 --> 01:23:38.590
Wenn die Registrierung ausbleibt, dann muss halt kein Rückruf

01:23:38.590 --> 01:23:38.950
passieren.

01:23:39.450 --> 01:23:41.310
Aber der Anwendungskern funktioniert dann trotzdem.

01:23:47.570 --> 01:23:51.470
Das ist alles furchtbar, was da steht.

01:23:51.690 --> 01:23:53.230
Das ist, glaube ich, auch die letzte Folie.

01:23:54.370 --> 01:23:56.970
Und ich muss gestehen, dass ich die nicht durchgelesen habe, bevor ich

01:23:56.970 --> 01:23:57.630
hierher gekommen bin.

01:23:57.710 --> 01:23:58.670
Das hätte ich vielleicht tun sollen.

01:24:11.500 --> 01:24:13.600
Sie haben es jetzt genauso schnell gelesen wie ich.

01:24:14.360 --> 01:24:15.400
Und Sie müssen auch lachen.

01:24:20.010 --> 01:24:23.530
Das ist eine sehr verschwurbelte Darstellung von dem, was wir auf der

01:24:23.530 --> 01:24:24.630
letzten Folie gesehen haben.

01:24:26.130 --> 01:24:26.730
Von dem hier.

01:24:28.530 --> 01:24:30.110
Und zwar die...

01:24:30.110 --> 01:24:32.310
Ich lehne mich jetzt mal aus dem Fenster, vielleicht die C-Variante

01:24:32.310 --> 01:24:32.710
von dem.

01:24:34.170 --> 01:24:37.790
Wenn Sie eine hübsche Hochsprache haben, so wie C-Sharp zum Beispiel,

01:24:38.110 --> 01:24:42.230
oder überhaupt .NET, dann können Sie Delegates benutzen.

01:24:42.410 --> 01:24:44.250
Sie können Methoden übergeben.

01:24:45.230 --> 01:24:48.910
Das heißt, die Benutzerschnittstelle sagt dem Anwendungskern, hier

01:24:48.910 --> 01:24:52.630
hast du eine Methode von mir, ruf die auf, wenn ein bestimmtes

01:24:52.630 --> 01:24:53.390
Ereignis eintritt.

01:24:54.070 --> 01:24:55.390
Das kann man mit Delegates machen.

01:24:55.890 --> 01:25:01.310
In C können Sie natürlich Pointer übergeben, also Zeiger auf eine

01:25:01.310 --> 01:25:03.830
Methode und das kann man genau so machen.

01:25:03.970 --> 01:25:06.610
Die Benutzerschnittstelle sagt dem Anwendungskern übrigens, hier ist

01:25:06.610 --> 01:25:09.990
ein Zeiger, das ist eine Speicheradresse, da liegt eine Methode, die

01:25:09.990 --> 01:25:12.150
kannst du aufrufen, wenn dieses Ereignis eintritt.

01:25:13.170 --> 01:25:14.610
In Java geht das leider nicht.

01:25:15.270 --> 01:25:16.550
Weder das eine noch das andere.

01:25:18.590 --> 01:25:21.650
Aber diese Erklärungen können Sie sich hier nochmal durchlesen.

01:25:22.630 --> 01:25:25.970
Der Register Mouse Listener, das ist vielleicht was, was Sie in Java

01:25:25.970 --> 01:25:26.810
wiederfinden.

01:25:28.470 --> 01:25:31.530
Aber da geben Sie dann in der Regel eine ganze Klasse an.

01:25:34.010 --> 01:25:35.730
Kein Zeiger auf eine Methode.

01:25:36.590 --> 01:25:40.290
Okay, und das wichtige ist, der letzte Punkt, wenn Sie sowas haben wie

01:25:40.290 --> 01:25:43.590
ein Callback, so ein Rückruf, dann heißt es nicht, dass die Benutzt

01:25:43.590 --> 01:25:45.330
Relation zyklisch wird dadurch.

01:25:46.650 --> 01:25:51.450
Das ist also zulässig, obwohl dadurch optisch erstmal ein Zyklus

01:25:51.450 --> 01:25:51.870
entsteht.

01:25:52.830 --> 01:25:54.750
So, jetzt die letzte Folie von dem Kapitel.

01:25:55.090 --> 01:25:59.670
Wenn Sie sich die Historie reinziehen wollen, das ist der Herr Parnas,

01:26:00.670 --> 01:26:05.470
der hat das Beispiel gemacht mit dem Verschieber und meine Schätzung

01:26:05.470 --> 01:26:10.430
mit 1979 war offensichtlich völlig daneben, so um zehn Jahre

01:26:10.430 --> 01:26:10.890
wahrscheinlich.

01:26:12.030 --> 01:26:14.550
Wenn Sie Interesse an der Historie haben, gucken Sie sich das an.

01:26:14.950 --> 01:26:18.570
Wenn Sie kein Interesse an der Historie haben, dann schauen Sie sich

01:26:18.570 --> 01:26:21.090
bitte wenigstens die Pflichtlektüre an.

01:26:23.370 --> 01:26:27.390
Da ist ein Paper dabei von 1979 und noch ein bisschen was anderes.

01:26:28.790 --> 01:26:32.670
Gucken Sie sich das an, mindestens mit einem halben Auge, besser ganz.

01:26:33.850 --> 01:26:37.530
Sie können ziemlich sicher gehen, dass wir in der Klausur keine Frage

01:26:37.530 --> 01:26:40.230
stellen, was steht in einem dieser Paper.

01:26:41.350 --> 01:26:44.170
Aber wenn Sie verstanden haben, was da drin erklärt wird, dann haben

01:26:44.170 --> 01:26:47.090
Sie wahrscheinlich was gelernt, was Sie wieder brauchen können.

01:26:48.530 --> 01:26:49.870
Damit hören wir auf.

01:26:50.790 --> 01:26:53.530
Nächstes Mal geht es weiter mit dem objektorientierten Entwurf und

01:26:53.530 --> 01:26:54.970
jetzt wünsche ich Ihnen guten Appetit.

