aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Info/12/Listen/Kompositum/.gitignore2
-rw-r--r--Info/12/Listen/Kompositum/slides-wiederholung.md91
-rw-r--r--Info/12/Listen/Kompositum/slides.md463
-rw-r--r--Info/12/Listen/Trennung_Strukur_Daten/.gitignore2
-rw-r--r--Info/12/Listen/Trennung_Strukur_Daten/slides-wiederholung.md60
-rw-r--r--Info/12/Listen/Trennung_Strukur_Daten/slides.md174
6 files changed, 792 insertions, 0 deletions
diff --git a/Info/12/Listen/Kompositum/.gitignore b/Info/12/Listen/Kompositum/.gitignore
new file mode 100644
index 00000000..dd6b8c3d
--- /dev/null
+++ b/Info/12/Listen/Kompositum/.gitignore
@@ -0,0 +1,2 @@
+slides-wiederholung.pdf
+slides-wiederholung.pptx
diff --git a/Info/12/Listen/Kompositum/slides-wiederholung.md b/Info/12/Listen/Kompositum/slides-wiederholung.md
new file mode 100644
index 00000000..68e6c5c2
--- /dev/null
+++ b/Info/12/Listen/Kompositum/slides-wiederholung.md
@@ -0,0 +1,91 @@
+---
+author: Florian Fischer
+theme: metropolis
+aspectratio: 169
+---
+
+## \faIcon{comments} Wiederholung: Allgemeine Liste \hfill 1/3
+
+Nimm Stellung zu folgender Aussage: \vspace{0.25cm}
+
+> Bei jeder Listen-Implementierung, müssen immer die Klassen für die Daten-Objekte im Code angepasst werden.
+
+::: {.columns}
+:::: {.column width=50%}
+```java
+class Praxis {
+ ...
+ Patient find(...) {}
+}
+class Knoten {
+ Knoten next;
+ Patient daten;
+ ...
+}
+```
+::::
+
+:::: {.column width=50%}
+```java
+class CallCenter {
+ ...
+ Kunde find(...) {}
+}
+class Knoten {
+ Knoten next;
+ Kunde daten;
+ ...
+}
+```
+::::
+:::
+
+\pause
+
+\begin{tikzpicture}[overlay, remember picture]
+ \node[rotate=5,scale=2] at (4, 4.3) {\large \boldred{Falsch}};
+\end{tikzpicture}
+
+Generics!
+
+## \faIcon{comments} Wiederholung: Find-Aufruf \hfill 2/3
+
+Nimm Stellung zu folgender Aussage: \vspace{0.5cm}
+
+> Folgende Meldung ist normal, beim Versuch ein Element in einer leeren Liste zu finden.
+> `NullPointerException in thread main thread: Auf ein Attribut/eine Methode von null kann nicht zugegriffen werden.`
+
+\pause
+
+\begin{tikzpicture}[overlay, remember picture]
+ \node[rotate=5,scale=2] at (4, 0.3) {\large \boldred{Falsch}};
+\end{tikzpicture}
+
+\pause
+
+Eine **NullPointerException** ist ein \boldred{Programmabsturz}, da nicht auf ein nicht vorhandenes Objekt zugegriffen werden kann.
+
+## \faIcon{comments} Wiederholung: Find \hfill 3/3
+
+Nimm Stellung zu folgender Aussage: \vspace{0.5cm}
+
+> Folgender Code implementiert die rekursive Methode, um einen Eintrag in einer Liste zu finden.
+
+```java
+Entry find(Data tofind) {
+ if (data == tofind) // Ich bin gesucht
+ return this.data;
+
+ return next.find(tofind); // Ich frage den Nächsten
+ }
+```
+
+\pause
+
+\begin{tikzpicture}[overlay, remember picture]
+ \node[rotate=5,scale=2] at (4, 0.3) {\large \boldred{Falsch}};
+\end{tikzpicture}
+
+\pause
+
+Wenn es keinen Nächsten mehr gibt, stürzt das Programm ab.
diff --git a/Info/12/Listen/Kompositum/slides.md b/Info/12/Listen/Kompositum/slides.md
new file mode 100644
index 00000000..cbda020b
--- /dev/null
+++ b/Info/12/Listen/Kompositum/slides.md
@@ -0,0 +1,463 @@
+---
+author: Florian Fischer
+theme: metropolis
+aspectratio: 169
+---
+
+```{.include}
+slides-wiederholung.md
+```
+
+## {.standout}
+
+Je weniger benötigte Bedingungen, desto einfacher ist der Code und desto weniger Fehler sind möglich.
+
+## Listenabschluss
+
+Wie werden wir die Überprüfung des Listenendes los?
+
+::: {.columns}
+:::: {.column width=50%}
+```java
+if (first == null) ...
+```
+::::
+
+:::: {.column width=50%}
+```java
+if (next == null) ...
+```
+::::
+:::
+
+### \faIcon{lightbulb} Idee
+
+\pause
+
+Wir nutzen ein besonderes Abschluss-Objekt, das immer am Ende steht.
+
+## Listenabschluss: Objektdiagramm
+
+\begin{tikzpicture}
+ \begin{object}[text width=3cm]{liste}{0,0}
+ \attribute{anfang}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{node1}{-5,-2.5}
+ \attribute{next}
+ \attribute{daten}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{daten1}{-5,-4.5}
+ \attribute{inhalt}
+ \end{object}
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (d1) at (-5.7, -3.85) {};
+ \draw[line width=2pt, draw=blue!80] (d1) edge [bend left=15, -latex] (daten1);
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (n1) at (-5.8, -3.3) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (n1) edge [bend right=15] (-2, -2.75);
+
+ \begin{object}[text width=3.5cm]{node2}{0,-2.5}
+ \attribute{next}
+ \attribute{daten}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{daten2}{0,-4.5}
+ \attribute{inhalt}
+ \end{object}
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (d2) at (-0.7, -3.85) {};
+ \draw[line width=2pt, draw=blue!80] (d2) edge [bend left=15, -latex] (daten2);
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (n1) at (-0.8, -3.3) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (n1) edge [bend right=15] (3, -2.75);
+
+ \begin{object}[fill=white!30!blue, text width=3.5cm]{abschluss}{5,-2.5}
+ \end{object}
+
+ \only<2->{
+ \node[text width=4cm, below=of abschluss] {Jetzt hat jeder Knoten immer einen Nachfolger.};
+ }
+
+ % Anfang
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (anfang) at (-1.6, -0.81) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (anfang) edge [bend right=25] (-5.1, -2.45);
+\end{tikzpicture}
+
+## Listenabschluss: Klassendiagramm
+
+::: {.columns}
+:::: {.column width=50%}
+\begin{tikzpicture}
+ \node[draw] (list) {\large Liste};
+ \node[draw] (leaf) at (-1.5, -2) {\large Abschluss};
+ \node[draw] (node) at (1.5, -2) {\large Knoten};
+
+ \draw[red] (list) edge[sloped, above] node {anfang} (leaf);
+ \draw[red] (list) edge[sloped, below] node {anfang} (node);
+ \draw (node.north) |- ($(node.north) + (0, 0.5cm)$) edge[above] node {\textcolor{red}{0,1 < Nachfolger}} ($(node.north) + (2.5cm, 0.5cm)$);
+ \draw ($(node.north) + (2.5cm, 0.5cm)$) |- (node.east);
+\end{tikzpicture}
+::::
+
+:::: {.column width=50%}
+```java
+class Liste {
+ // Kann keinen Abschluss speichern!
+ Knoten first;
+ // Kann keinen Knoten speichern!
+ Abschluss first;
+}
+```
+::::
+:::
+
+Ein Referenzattribut kann nicht mehrere Datentypen haben!
+
+## Listenabschluss: Klassendiagramm Polymorphismus
+
+### \faIcon{lightbulb} Idee
+
+Eine gemeinsame Oberklasse!
+
+::: {.columns}
+:::: {.column width=50%}
+\begin{tikzpicture}
+ \node[draw] (list) {\large Liste};
+ \node[draw, text width=2.5cm, align=center] (abstract) at (0, -1.5) {\large ListenElement \newline <abstract>};
+ \node[draw] (leaf) at (-1.5, -3) {\large Abschluss};
+ \node[draw] (node) at (1.5, -3) {\large Knoten};
+
+ \draw (list) edge[left] node {anfang} (abstract);
+ \draw[-{Triangle[open, scale=1.5]}] (leaf) -- (abstract);
+ \draw[-{Triangle[open, scale=1.5]}] (node) -- (abstract);
+ \draw ($(node.north) + (0.5cm, 0)$) |- (abstract.east);
+\end{tikzpicture}
+::::
+
+:::: {.column width=50%}
+```java
+class Liste {
+ // Abschluss oder Knoten
+ ListenElement first;
+}
+```
+::::
+:::
+
+\vspace{0.25cm}
+Ein Referenzattribut auf eine Oberklasse kann Objekte aller Unterklassen speichern.
+
+## Kompositum
+
+:::{.env .merke}
+Das \boldred{Kompositum}, ist ein **Entwurfsmuster** (bewährte Lösung), bei dem primitive Objekte sowie ihre **Komposition** von einer gemeinsamen abstrakten Klasse erben.
+Die Vererbung ermöglicht, alle Objekte gleich zu behandeln.
+:::
+
+::: {.columns}
+:::: {.column width=50%}
+**Beispiel: Liste** `\\[0.25cm]`{=latex}
+
+\begin{tikzpicture}
+ \node[draw, text width=2.5cm, align=center] (abstract) at (0, -1.5) {\large Listeneintrag \newline <abstract>};
+ \node[draw] (leaf) at (-1.5, -3) {\large Abschluss};
+ \node[draw] (node) at (1.5, -3) {\large Eintrag};
+
+ \draw[-{Triangle[open, scale=1.5]}] (leaf) -- (abstract);
+ \draw[-{Triangle[open, scale=1.5]}] (node) -- (abstract);
+ \draw ($(node.north) + (0.5cm, 0)$) |- (abstract.east);
+\end{tikzpicture}
+::::
+
+:::: {.column width=50%}
+**Beispiel: Dateisystem** `\\[0.25cm]`{=latex}
+
+\begin{tikzpicture}
+ \node[draw, text width=3cm, align=center] (abstract) at (0, -1.5) {\large Verzeichniseintrag \newline <abstract>};
+ \node[draw] (leaf) at (-1.5, -3) {\large Datei};
+ \node[draw] (node) at (1.5, -3) {\large Verzeichnis};
+
+ \draw[-{Triangle[open, scale=1.5]}] (leaf) -- (abstract);
+ \draw[-{Triangle[open, scale=1.5]}] (node) -- (abstract);
+ \draw ($(node.north) + (0.5cm, 0)$) |- (abstract.east);
+\end{tikzpicture}
+::::
+:::
+
+
+## Liste mit Kompositum
+::: {.columns}
+:::: {.column width=40%}
+\begin{tikzpicture}
+\begin{abstractclass}[text width=5cm]{Listenelement}{0,0}
+ \operation{naechsterSetzen(Listenelement)}
+ \operation{naechsterGeben(): Listenelement}
+ \operation{datenGeben(): Daten}
+\end{abstractclass}
+\end{tikzpicture}
+::::
+
+:::: {.column width=60%}
+### \faIcon{desktop} Arbeitsauftrag: Neue Liste \hfill 10 min
+
+Erstelle in einem **neuen** Workspace, die fünf Klassen:
+
+* `Liste`
+* `Listenelement`
+* `Eintrag`
+* `Abschluss`
+* `Daten`
+
+... mit den dir bekannten Attributen, Methoden und Vererbung.
+
+\textit{Welche Daten die Liste verwaltet, ist dir überlassen.}
+
+::::
+:::
+
+## Liste mit Kompositum: Minimal Version \hfill 1/2
+
+```java
+class Liste {
+ Listenelement anfang;
+}
+abstract class Listenelement {
+ abstract void naechsterSetzen(ListenElement n);
+ abstract ListenElement naechsterGeben();
+ abstract Daten datenGeben();
+}
+class Abschluss extends Listenelement {
+ void naechsterSetzen(ListenElement n) {}
+ ListenElement naechsterGeben() { return this; }
+ Daten datenGeben() { return null; }
+}
+```
+
+## Liste mit Kompositum: Minimal Version \hfill 2/2
+
+```java
+class Eintrag extends Listenelement {
+ Listenelement nachfolger;
+ Daten daten;
+
+ Eintrag(Daten d) { daten = d; }
+
+ void naechsterSetzen(ListenElement n) { nachfolger = n; }
+ ListenElement naechsterGeben() { return nachfolger; }
+ Daten datenGeben() { return daten; }
+}
+class Daten {}
+```
+
+## {.standout}
+
+Ist das jetzt wirklich besser?
+
+## Vergleich: `getLength()`
+
+::: {.columns align=center}
+:::: {.column width=47.5%}
+```java
+class Liste { // [...]
+ int getLength() {
+ if (first == null) return 0;
+ return first.getLength();
+ }
+}
+class Eintrag { // [...]
+ int getLength() {
+ if (next == null) return 0;
+ return next.getLength() + 1;
+ }
+}
+```
+::::
+
+:::: {.column width=5%}
+\boldred{vs.}
+::::
+
+:::: {.column width=47.5%}
+```java
+class Liste { // [...]
+ int getLength() {
+ return first.getLength();
+ }
+}
+class Eintrag { // [...]
+ int getLength() {
+ return next.getLength() + 1;
+ }
+}
+class Abschluss {
+ int getLength() {
+ return 0;
+ }
+}
+```
+::::
+:::
+
+## \faIcon{hands-helping} Arbeitsauftrag: Methoden mit Kompositum \hfill 15 min
+
+Sucht euch zu zweit eine Methode aus.
+
+* `void vorneEinfuegen(Daten)`
+* `void hintenEinfuegen(Daten)`
+* `Daten vorneEntfernen()`
+* `Daten endeGeben()`
+* `void elementEntfernen(Daten)`
+* `Daten hintenEntfernen()`
+
+Erarbeitet einen Algorithmus für eure Liste mit Kompositum:
+
+1. Visualisiert euren Algorithmus mit Sequenz-/ oder Objektdiagrammen.
+2. Implementiert euren Algorithmus in Java oder Pseudocode.
+
+## \faIcon{desktop} Arbeitsauftrag: Kompositum implementieren
+
+Implementiere eine Liste mit dem Entwurfsmuster **Kompositum**.
+
+Deine Liste sollte die folgenden Methoden rekursiv implementieren:
+
+* `int laengeGeben()`
+* `void vorneEinfuegen(Daten)`
+* `void hintenEinfuegen(Daten)`
+* `Daten vorneEntfernen()`
+* `Daten endeGeben()`
+* `Daten elementEntfernen(Daten)`
+* `Daten hintenEntfernen()`
+
+### \faIcon{earlybirds} Für Schnelle:
+
+Implementiere eine allgemeine Liste, die mit Hilfe von **Generics** ohne Code-Änderungen, Objekte beliebiger Klassen verwalten kann.
+
+## \faIcon{desktop} Implementierung: `int laengeGeben()`
+
+```java
+class Liste { // [...]
+ int laengeGeben() {
+ return anfang.getLength();
+ }
+}
+class Eintrag { // [...]
+ int laengeGeben() {
+ return nachfolger.getLength() + 1;
+ }
+}
+class Abschluss {
+ int laengeGeben() {
+ return 0;
+ }
+}
+```
+
+## Implementierung: `void vorneEinfuegen(daten)`
+
+```java
+class Liste { // [...]
+ void vorneEinfuegen(daten) {
+ Eintrag n = new Eintrag(daten);
+ n.naechsterSetzen(first);
+ anfang = n;
+ }
+}
+class Eintrag { // [...]
+ void naechsterSetzen(Listeneintrag n) {
+ nachfolger = n;
+ }
+}
+class Abschluss {
+ void naechsterSetzen(Listeneintrag n) {}
+}
+```
+
+## Implementierung: `void hintenEinfuegen(daten)`
+
+```java
+class Liste { // [...]
+ void hintenEinfuegen(Daten daten) {
+ anfang = anfang.hintenEinfuegen(daten);
+}}
+class Eintrag { // [...]
+ Listeneintrag hintenEinfuegen(Daten daten) {
+ nachfolger = nachfolger.hintenEinfuegen(daten);
+ return this;
+}}
+class Abschluss {
+ Listeneintrag hintenEinfuegen(Daten daten) {
+ Eintrag n = new Eintrag(daten);
+ n.naechsterSetzen(this);
+ return n;
+ }
+}
+```
+
+## Implementierung: `Daten vorneEntfernen()`
+
+```java
+class Liste { // [...]
+ Daten vorneEntfernen() {
+ Daten d = anfang.datenGeben();
+ anfang = anfang.naechsterGeben();
+ return d;
+ }
+}
+class Abschluss {
+ ListenElement naechsterGeben() { return this; }
+}
+```
+
+## Implementierung: `Daten endeGeben()`
+```java
+class Liste { // [...]
+ Daten endeGeben() {
+ return anfang.endeGeben(null);
+ }
+}
+class Eintrag {
+ Daten endeGeben(Daten prev) {
+ return nachfolger.endeGeben(this.daten);
+ }
+}
+class Abschluss {
+ Daten endeGeben(Daten prev) {
+ return prev;
+ }
+}
+```
+
+## Implementierung: `Daten elementEntfernen(daten)`
+
+```java
+class Liste { // [...]
+ void elementEntfernen(Daten daten) {
+ anfang.elementEntfernen(daten);
+ }
+}
+class Eintrag {
+ void elementEntfernen(Daten daten) {
+ if (nachfolger.datenGeben() == daten) {
+ nachfolger = nachfolger.naechsterGeben();
+ } else {
+ nachfolger.elementEntfernen(daten);
+ }
+ }
+}
+class Abschluss {
+ Daten elementEntfernen(Daten daten) { }
+}
+```
+
+## Implementierung: `Daten hintenEntfernen()`
+```java
+class Liste { // [...]
+ Daten hintenEntfernen() {
+ Daten ende = anfang.endeGeben(null);
+ anfang.elementEntfernen(ende);
+ return ende;
+ }
+}
+```
diff --git a/Info/12/Listen/Trennung_Strukur_Daten/.gitignore b/Info/12/Listen/Trennung_Strukur_Daten/.gitignore
new file mode 100644
index 00000000..dd6b8c3d
--- /dev/null
+++ b/Info/12/Listen/Trennung_Strukur_Daten/.gitignore
@@ -0,0 +1,2 @@
+slides-wiederholung.pdf
+slides-wiederholung.pptx
diff --git a/Info/12/Listen/Trennung_Strukur_Daten/slides-wiederholung.md b/Info/12/Listen/Trennung_Strukur_Daten/slides-wiederholung.md
new file mode 100644
index 00000000..2b8c0d89
--- /dev/null
+++ b/Info/12/Listen/Trennung_Strukur_Daten/slides-wiederholung.md
@@ -0,0 +1,60 @@
+---
+author: Florian Fischer
+theme: metropolis
+aspectratio: 169
+header-includes:
+ \usepackage{pgf-umlsd}
+---
+
+## \faIcon{comments} Wiederholung: Sonderfälle \hfill 1/3
+
+Nimm Stellung zu folgender Aussage: \vspace{1cm}
+
+> Alle Sonderfälle: leere Liste, gesuchtes Element ist das Erste/Letzte müssen in der Liste behandelt werden.
+
+\pause
+
+\begin{tikzpicture}[overlay, remember picture]
+ \node[rotate=5,scale=2] at (0.75\textwidth, 2) {\large \textbf{\textcolor{green!80!black}{Korrekt}}};
+\end{tikzpicture}
+
+## \faIcon{comments} Wiederholung: Sequenzdiagramm \hfill 2/3 {.t}
+
+Nimm Stellung zu folgender Aussage: \vspace{0.5cm}
+
+> Das Sequenzdiagramm zeigt einen Ablauf der rekursiven Methode `getLength()`.
+
+\centering
+\begin{sequencediagram}
+ \newthread{A}{playlist}{}
+ \newinst[1.5]{B}{s1}{}
+ \newinst[1.5]{C}{s2}{}
+ \newinst[1.5]{D}{s3}{}
+ \begin{call}{A}{?}{B}{null}
+ \begin{call}{B}{?}{C}{null}
+ \begin{call}{C}{?}{D}{null}
+ \end{call}
+ \end{call}
+ \end{call}
+\end{sequencediagram}
+
+\pause
+
+\begin{tikzpicture}[overlay, remember picture]
+ \node[rotate=5,scale=2] at (5, 3.5) {\large \boldred{Falsch}};
+\end{tikzpicture}
+
+## \faIcon{comments} Wiederholung: Arten von Listen \hfill 3/3 {.t}
+
+Nimm Stellung zu folgender Aussage: \vspace{0.75cm}
+
+> Eine rekursiver Methodenaufruf bedeutet, dass das Objekt eine Methode der eigenen Klasse aufruft.
+
+\pause
+
+\begin{tikzpicture}[overlay, remember picture]
+ \node[rotate=5,scale=2] at (4, 0.3) {\large \boldred{Falsch}};
+\end{tikzpicture}
+
+\vspace{0.25cm}
+> Eine rekursiver Methodenaufruf bedeutet, dass das Objekt die \boldred{gleiche} Methode der Klasse aufruft.
diff --git a/Info/12/Listen/Trennung_Strukur_Daten/slides.md b/Info/12/Listen/Trennung_Strukur_Daten/slides.md
new file mode 100644
index 00000000..1e24602d
--- /dev/null
+++ b/Info/12/Listen/Trennung_Strukur_Daten/slides.md
@@ -0,0 +1,174 @@
+---
+author: Florian Fischer
+theme: metropolis
+aspectratio: 169
+header-includes:
+ \usepackage{pgf-umlsd}
+---
+
+```{.include}
+slides-wiederholung.md
+```
+
+## \faIcon{chalkboard-teacher} Wiederholung: Die Liste
+
+\centering
+\begin{tikzpicture}
+ \begin{object}[text width=3cm]{liste}{0,0}
+ \attribute{anfang}
+ \attribute{ende}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{lied1}{-5,-2.5}
+ \attribute{name = "foo"}
+ \attribute{next}
+ \end{object}
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (n1) at (-5.8, -3.9) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (n1) edge [bend right=15] (-2, -2.75);
+
+ \begin{object}[text width=3.5cm]{lied2}{0,-2.5}
+ \attribute{name = "bar"}
+ \attribute{next}
+ \end{object}
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (n1) at (-0.8, -3.9) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (n1) edge [bend right=15] (3, -2.75);
+
+ \begin{object}[text width=3.5cm]{lied3}{5,-2.5}
+ \attribute{name = "baz"}
+ \attribute{next}
+ \end{object}
+
+ % Anfang
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (anfang) at (-1.6, -0.81) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (anfang) edge [bend right=25] (-5.1, -2.45);
+
+ % Ende
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (ende) at (-0.35, -1.4) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (ende) edge [bend left=20] (5.1, -2.45);
+\end{tikzpicture}
+
+## {.standout}
+
+Könnten wir mit unserer Playlist nicht auch Kurzvideos verwalten?
+
+## Problem
+
+### Daten und Verwaltung
+
+In unserer Implementierung ist der Code für die Daten und die Verwaltung der Liste vermischt.
+
+\pause
+
+### \faIcon{lightbulb} Trennung von Struktur und Daten
+
+Wie bekommen wir den Code zur Verwaltung von dem Code für die Daten (Songs, Videos, Kund*innen) getrennt?
+
+##
+
+\begin{tikzpicture}
+ \begin{object}[text width=3cm]{liste}{0,0}
+ \attribute{anfang}
+ \attribute{ende}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{node1}{-5,-2.5}
+ \attribute{next}
+ \attribute{daten}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{daten1}{-5,-4.5}
+ \attribute{inhalt}
+ \end{object}
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (d1) at (-5.7, -3.85) {};
+ \draw[line width=2pt, draw=blue!80] (d1) edge [bend left=15, -latex] (daten1);
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (n1) at (-5.8, -3.3) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (n1) edge [bend right=15] (-2, -2.75);
+
+ \begin{object}[text width=3.5cm]{node2}{0,-2.5}
+ \attribute{next}
+ \attribute{daten}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{daten2}{0,-4.5}
+ \attribute{inhalt}
+ \end{object}
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (d2) at (-0.7, -3.85) {};
+ \draw[line width=2pt, draw=blue!80] (d2) edge [bend left=15, -latex] (daten2);
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (n1) at (-0.8, -3.3) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (n1) edge [bend right=15] (3, -2.75);
+
+ \begin{object}[text width=3.5cm]{node3}{5,-2.5}
+ \attribute{next}
+ \attribute{daten}
+ \end{object}
+
+ \begin{object}[text width=3.5cm]{daten3}{5,-4.5}
+ \attribute{inhalt}
+ \end{object}
+
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (d3) at (4.3, -3.85) {};
+ \draw[line width=2pt, draw=blue!80] (d3) edge [bend left=15, -latex] (daten3);
+
+ % Anfang
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (anfang) at (-1.6, -0.81) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (anfang) edge [bend right=25] (-5.1, -2.45);
+
+ % Ende
+ \node[fill=black, circle, minimum size=0.005cm, scale=0.5] (ende) at (-0.35, -1.4) {};
+ \draw[line width=2pt, -latex, draw=blue!80] (ende) edge [bend left=20] (5.1, -2.45);
+\end{tikzpicture}
+
+## \faIcon{pencil-alt} Arbeitsauftrag: Klassendiagramm \hfill 5min
+
+Erweitere das Klassendiagramm der Liste, sodass Daten-/ und Listenverwaltung von getrennten Klassen umgesetzt werden.
+
+### Einfaches Klassendiagramm {.tipp}
+
+\centering
+\begin{tikzpicture}
+ \node[draw] (list) {\large Liste};
+ \node[draw] (song) at (5, 0) {\large Lied};
+
+ \draw ($(list.east) + (0, 0.1cm)$) edge[above] node {hat als Anfang > 0,1} ($(song.west) + (0, 0.1cm)$);
+ \draw ($(list.east) - (0, 0.1cm)$) edge[below] node {hat als Ende > 0,1} ($(song.west) - (0, 0.1cm)$);
+ \draw (song.north) |- ($(song.north) + (0, 0.5cm)$) edge[above] node {0,1 < hat als Nachfolger} ($(song.north) + (3.5cm, 0.5cm)$);
+ \draw ($(song.north) + (3.5cm, 0.5cm)$) |- (song.east);
+\end{tikzpicture}
+
+## Klassendiagramm mit Trennung zwischen Struktur und Inhalt
+
+\centering
+\begin{tikzpicture}
+ \node[draw] (list) {\large Liste};
+ \node[draw] (node) at (5, 0) {\large ListenElement};
+ \node[draw] (song) at (5, -3) {\large Lied};
+
+ \draw ($(list.east) + (0, 0.1cm)$) edge[above] node {anfang > 0,1} ($(node.west) + (0, 0.1cm)$);
+ \draw ($(list.east) - (0, 0.1cm)$) edge[below] node {ende > 0,1} ($(node.west) - (0, 0.1cm)$);
+ \draw (node.north) |- ($(node.north) + (0, 0.5cm)$) edge[above] node {0,1 < nachfolger} ($(node.north) + (3.5cm, 0.5cm)$);
+ \draw ($(node.north) + (3.5cm, 0.5cm)$) |- (node.east);
+
+ \draw (song.north) edge[above] node[rotate=-90] {verwaltet > 1} (node.south);
+\end{tikzpicture}
+
+## \faIcon{desktop} Arbeitsauftrag: Trennung zwischen Struktur und Inhalt
+
+1. Dupliziere deinen Listen Workspace
+2. Übertrage die Rekursiven Methoden aus der Klasse Song in eine Klasse `ListEntry`.
+3. Passe die Methoden der Playlist entsprechend an, dass jeder Song von einem `ListEntry` Objekt verwaltet wird.
+
+### Beispiel: `void add(Song s)`{.java} {.example}
+```java
+ void add(Song s) {
+ ListEntry e = new ListEntry(s); // Listenelement für s anlegen
+ if (last)
+ last.next = e; // e kommt nach dem aktuell Letzten
+ last = e; // Das Element wirdam Ende eingefügt
+ }
+```