Compare commits

...

17 Commits

Author SHA1 Message Date
Henri Burau 0a446b4058 change url 2023-05-16 10:58:56 +02:00
Henri Burau 7c893cf79c
Add Nebenläufigkeit 2021-06-26 15:00:34 +02:00
Henri Burau f6d3032e74
Add termin8 2021-06-24 13:15:14 +02:00
Burau, Henri e16988cfcd Merge branch 'master' of git.haw-hamburg.de:pm2-tutorium/slides 2021-06-24 09:24:27 +02:00
Burau, Henri d2aa79ac9e Add termin 6 2021-06-24 09:24:17 +02:00
Henri Burau c63851ddb9
Add content for SOLID principals 2021-06-17 15:58:56 +02:00
Henri Burau ade9c90265
Finish OO design 2021-06-17 15:27:32 +02:00
Henri Burau 71799703fe
Add test 2021-06-17 13:16:39 +02:00
Henri Burau 3968c9f8c2
Start work on termin7 2021-06-17 13:13:02 +02:00
Henri Burau 98314fc5ee Add termin slide 2021-06-17 13:00:30 +02:00
Henri Burau f21087b791 Update ingress to newer resource 2021-06-17 12:59:39 +02:00
Henri Burau a062672e2f Add termin5 2021-06-17 11:02:45 +02:00
Burau, Henri af3772f76d Add wam-ansatz divider 2021-06-03 12:27:02 +02:00
Burau, Henri 02233fa5ec Add excercise 2021-05-27 14:40:23 +02:00
Burau, Henri f8c3edb91d Add termin 4 2021-05-27 14:21:10 +02:00
Burau, Henri e4d91c1794 Add termin3 stuff 2021-05-27 10:20:36 +02:00
Burau, Henri efafd8f037 Change pipeline 2021-05-20 14:54:24 +02:00
26 changed files with 914 additions and 16 deletions

View File

@ -1,7 +1,7 @@
<!--
title: Termin 1
description: Folien für den ersten Termin in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

View File

@ -1,7 +1,7 @@
<!--
title: Termin 2
description: Folien für den ersten Termin in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

View File

@ -1,7 +1,7 @@
<!--
title: Termin 3
description: Folien für den ersten Termin in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

29
04-termin.md Normal file
View File

@ -0,0 +1,29 @@
<!--
title: Termin 4
description: Folien für den ersten Termin in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Termin 4
---
# Fragen
---
# Links
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
- Aufgaben
- Tutoriumsfolien
---
# Plan für heute
Level 6 Themen:
- **Werkzeug & Material-Ansatz**
- **Entwurfsmuster**

31
05-termin.md Normal file
View File

@ -0,0 +1,31 @@
<!--
title: Termin 5
description: Folien für den ersten Termin in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Termin 5
---
# Fragen
---
# Links
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
- Aufgaben
- Tutoriumsfolien
---
# Plan für heute
Level 6 Themen:
- Werkzeug & Material-Ansatz
- Entwurfsmuster
- **Lambdas**
- **Streams**

31
06-termin.md Normal file
View File

@ -0,0 +1,31 @@
<!--
title: Termin 6
description: Folien für den ersten Termin in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Termin 6
---
# Fragen
---
# Links
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
- Aufgaben
- Tutoriumsfolien
---
# Plan für heute
Level 6 Themen:
- Werkzeug & Material-Ansatz
- Entwurfsmuster
- Lambdas und Streams
- **Werttypen**

40
07-termin.md Normal file
View File

@ -0,0 +1,40 @@
<!--
title: Termin 7
description: Folien für den ersten Termin in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Termin 7
---
# Fragen
---
# Links
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
- Aufgaben
- Tutoriumsfolien
* In Präsentationsansicht: [https://wi-pm2-tut.informatik.haw-hamburg.de](https://wi-pm2-tut.informatik.haw-hamburg.de/)
---
# Plan für heute
Level 7 Themen:
- *Organisatorisches*
- **Objektorientierter Entwurf**
---
# Plan
* Am 24.6. letzter Termin
* 1.7. findet nicht statt, aber es gibt eine Aufzeichnung.
* Prüfungsvorberreitung wird es auch in Form einer Aufzeichnung geben.
* Entweder Erklärung der Prüfung oder die ganze Prüfung aufgezeichnet.
* Fragen gerne auf Teams stellen. Am Montag den 5.7. um 11 Uhr gibt es noch eine Fragestunde.

39
08-termin.md Normal file
View File

@ -0,0 +1,39 @@
<!--
title: Termin 8
description: Folien für den ersten Termin in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Termin 8
---
# Fragen
---
# Links
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
- Aufgaben
- Tutoriumsfolien
* In Präsentationsansicht: [https://wi-pm2-tut.informatik.haw-hamburg.de](https://wi-pm2-tut.informatik.haw-hamburg.de/)
---
# Plan für heute
Level 7 Themen:
- Objektorientierter Entwurf
- **Nebenläufikeit 1**
---
# Plan
* Heute ist der letzte Termin.
* 1.7. findet nicht statt, aber es gibt eine Aufzeichnung.
* Prüfungsvorberreitung wird es im Anschluss geben, gibt es aber auch in aufgezeichneter Form.
* Fragen gerne auf Teams stellen. Am Montag den 5.7. um 11 Uhr gibt es noch eine Fragestunde, die auch aufgezeichnet wird.

39
09-termin.md Normal file
View File

@ -0,0 +1,39 @@
<!--
title: Termin 9
description: Folien für den ersten Termin in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Termin 9
---
# Fragen
---
# Links
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
- Aufgaben
- Tutoriumsfolien
* In Präsentationsansicht: [https://wi-pm2-tut.informatik.haw-hamburg.de](https://wi-pm2-tut.informatik.haw-hamburg.de/)
---
# Plan für heute
Level 7 Themen:
- Objektorientierter Entwurf
- Nebenläufikeit 1
- **Nebenläufikeit 2**
---
# Plan
* 1.7. findet nicht statt, aber es gibt eine Aufzeichnung.
* Prüfungsvorberreitung gibt es in aufgezeichneter Form und eine Referenzimplementation unter [https://git.haw-hamburg.de/pm2-tutorium/code/referenz-loesung-pm2-2019](https://git.haw-hamburg.de/pm2-tutorium/code/referenz-loesung-pm2-2019).
* Fragen gerne auf Teams stellen. Am Montag den 5.7. um 11 Uhr gibt es noch eine Fragestunde, die auch aufgezeichnet wird.

69
10-termin.md Normal file
View File

@ -0,0 +1,69 @@
<!--
title: Termin 9
description: Folien für den ersten Termin in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Termin 10
---
# Fragen
---
# Links
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
- Aufgaben
- Tutoriumsfolien
* In Präsentationsansicht: [https://wi-pm2-tut.informatik.haw-hamburg.de](https://wi-pm2-tut.informatik.haw-hamburg.de/)
---
# Plan für heute
Fragestunde
---
# Fragen
* Was ist die Lösung der Feinschmeckeraufgabe aus der Generics Vorlesung? "Wie mache ich aus einem `Sec<Object>` das nur `String` enthält ein `Set<String>`?"
* Warum ist in der Referenzlösung eine Map in der Wertklassenaufgabe?
* Wie wende ich die Regel "Producer extends consumer super (PECS)" an?
---
# Feinschmeckeraufgabe
---
# Map in Wertklasse
---
# PECS
"Producer extends consumer super" beschreibt das Benutzen von `extends` und `super` bei Collections als generische Parameter.
---
Wenn man in einer Methode nur Sachen aus einer Collection **entnimmt** dann ist die Collection für uns ein Producer und wir benutzen `extends`.
```java
public void listeAuf(Collection<? extends Thing> coll) {
// Sachen aus der Collection herrausnehmen
}
```
Wenn man nur Sachen in die Collection **einfügt** dann ist die Collection für uns ein Consumer und wir benutzen `super`.
```java
public void packeRein(Collection<? super Thing> coll) {
// Sachen in die Collection einfügen
}
```
Will man beides machen (einfügen und entnehmen) dann muss ein fester Typ genutzt werden.

View File

@ -1,7 +1,7 @@
<!--
title: Abstrakte Klasse
description: Folien für abstrakte Klassen in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
@ -86,13 +86,13 @@ abstract class DreidimensionaleForm {
# Übung
1) Müssen alle abstrakten Methoden eine abstrakten Klasse in einer Subklasse implementiert werden?
* Ja, denn ansonsten fehlt für manche Operationen die Implementation.
* Wenn die Subklasse nicht auch `abstract` sein darf, dann ja.
2) Sind alle Felder der abstrakten Klasse auch in der Subklasse enthalten?
* Ja
3) Darf auf alle Felder der Superklasse aus der Subklasse zugegriffen werden?
* Nur solange die Modifier `private`, `protected` oder `package private` sind.
* Nur solange die Modifier `public`, `protected` oder `package private` sind.
---

View File

@ -1,7 +1,7 @@
<!--
title: Assertions
description: Folien für Assertions in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

View File

@ -1,9 +1,10 @@
apiVersion: extensions/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
name: slides-ingress
spec:
tls:
@ -15,9 +16,12 @@ spec:
http:
paths:
- path: /
pathType: Prefix
backend:
serviceName: slides
servicePort: 80
service:
name: slides
port:
number: 80
---
@ -56,7 +60,7 @@ spec:
ports:
- containerPort: 8080
imagePullSecrets:
- name: slides-deploy
- name: pull-secret

37
entwurfsmuster.md Normal file
View File

@ -0,0 +1,37 @@
<!--
title: Entwurfstmuster
description: Folien für Entwurfsmuster in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Entwurfsmuster
## Gang of Four Design Patterns
---
# Grundlagen
Lösungsansätze für häufig auftretende Probleme beim entwickeln von Software. Entwickelt von Gamma et al. (1994) und im Buch Design Patterns erschienen. Die Entwurfsmuster werden in einem bestimmten Format angegeben:
* Name, des Entwurftmusters
* Problem, das gelöst werden soll
* Kontext, in dem sich das Problem stellt
* Lösung, durch eine Klassenhierarchie mit Interaktion
* Konsequenzen, die aus dem Muster entstehen (Vor- und Nachteile)
---
# Observer
"Definiere eine 1-zu-n-Abhängigkeit zwischen Objekten, so dass die Änderung des Zustands eines Objekts dazu führt, das alle abhängigen Objekte benachrichtigt und automatisch aktualisiert werden."
![width:500px](https://www.philipphauer.de/study/se/design-pattern/observer/observer-def-schema.svg)
*Bildquelle: [Philipp Hauer](https://www.philipphauer.de/study/se/design-pattern/observer.php)*
---
# Observer Implementation
![width:350px](https://i.ibb.co/jJtnCSb/mermaid-diagram-20210527132005.png)

View File

@ -1,7 +1,7 @@
<!--
title: Assertions
description: Folien für Assertions in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

View File

@ -1,7 +1,7 @@
<!--
title: Generizität
description: Folien für Generizität in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

73
lambdas.md Normal file
View File

@ -0,0 +1,73 @@
<!--
title: Lambdas
description: Folien für Lambdas in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Lambdas
---
# Grundlagen
Erlauben das Implementieren von Interfaces mit nur einer Methode.
Klassischerweise wurde dieses Problem mithilfe von anonymen inneren Klassen gelöst. Lambda-Ausdrücke sparen im Vergleich dazu deutlich an Code.
---
# Beispiel
Lambda
```java
_zaehlerUI.gibErhoeheButton().setOnAction(event -> {
_zaehler.zaehleHoch();
informiereUeberAenderung();
});
```
Anonyme innere Klasse
```java
_zaehlerUI.gibErhoeheButton().setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
_zaehler.zaehleHoch();
informiereUeberAenderung();
}
});
```
---
# Beispiel
```java
// Lambda ohne explizite Typen und return (type inference)
x -> x * 2
// Lambda mit explitizen Typen der formalen Parameter
(int x, int y) -> x + y
// Lambda mit return
(int x, int y) -> { return x * y + 2 }
```
---
# Deklaration
```java
@FunctionalInterface
public interface Filter<T> {
bool istGueltig(T obj);
}
```
```java
Filter<String> langGenug = (String text) -> text.length() > 10;
```
# Aufgabe
1) Die Klasse `ZaehlerWerkzeug` nutzt das Interface `Observer` um Änderungen von Subwerkzeugen zu erhalten. `ZaehlerWerkzeug` registriert sich mithilfe von anonymen inneren Klassen. Baue das System der Observer um, sodass Lambdas genutzt werden.

254
nebenlaeufigkeit.md Normal file
View File

@ -0,0 +1,254 @@
<!--
title: Nebenläufigkeit
description: Folien für Nebenläufigkeit in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Nebenläufigkeit
---
# Grundlagen
Computer führen mehr als eine Aufgabe gleichzeitig aus. Auch innerhalb eine Programms können wir quasi gleichzeitige Ausführung von Programmcode programmieren. Diese Art der Programmierung bezeichnen wir als nebenläufig.
Es gibt zwei verschiedene Ausführungseinheiten:
* **Prozesse**: Besitzen eigene Laufzeitresourcen, am wichtigsten auch einen eigenen Speicherbereich
* **Threads**: Sind leichtgewichtige Prozesse. Threads existieren in einem Prozess und teilen sich Laufzeitresourcen mit ihm, wie den Speicherbereich und geöffnete Dateien.
Die meisten JVMs laufen in einem einzigen Prozess.
---
# System Threads
Zwei Threads haben wir bereits benutzt. Den main-Thread und den GUI-Thread von JavaFX (`application thread`).
---
# Deklaration
In Java gibt es zwei Möglichkeiten einen neuen Thread zu erzeugen. Entweder man erbt von der Klasse `Thread` oder man implementiert das Interface `Runnable`.
---
# Von `Thread` erben
```java
class HelloThread extends Thread {
public void run() {
System.out.println("Hallo aus einem Thread");
}
}
```
```java
Thread thread = new HelloThread();
thread.start();
```
- Simpel: Einfache Implementation
- Unflexibel: Nebenläufige Klasse muss immer eine Subklasse von `Thread` sein
---
# `Runnable` implementieren
```java
class HelloThread implements Runnable {
public void run() {
System.out.println("Hallo aus einem Thread");
}
}
```
```java
Thread thread = new Thread(new HelloThread());
thread.start();
```
- Kompliziert: Etwas schwieriger zu starten
- Flexibel: Die nebenläufige Klasse kann beliebige Superklassen haben
---
# Einen Thread pausieren
Mithilfe der Methode `Thread.sleep(long milliseconds) throws InterruptedException` kann ein Thread in seiner Ausführung pausiert werden.
```java
class HelloThread implements Runnable {
public void run() {
System.out.println("Hallo aus einem Thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e ) {
e.printStacktrace();
}
System.out.println("Hallo 1 Sekunde später")
}
}
```
---
# Einen Thread unterbrechen
Ein Thread `thread1` kann von einem anderen Thread `thread2` mithilfe der Methode `thread1.interrupt()` unterbrochen werden. Wird ein Thread unterbrochen wird der `Interrupted-State` gesetzt. Der kann mithilfe der Methode `Thread.interrupted()` abgefragt werden. Ist der Thread aktuell pausiert wird die `InterruptedException` der Methode `sleep` geworfen.
In beiden Fällen kann der Thread selbst entscheiden ob er abbrechen will.
```java
Thread thread = new Thread(new LongRunningThread());
thread.start();
thread.interrupt();
```
---
# Auf einen Thread warten
Wenn wir aus einem Thread auf die Beendung eines anderen Threads warten wollen, können wir dafür die Methode `join()` nutzen.
```java
Thread thread = new Thread(new LongRunningThread());
thread.start();
System.out.println("Jetzt läuft der Thread");
thread.join();
System.out.println("Jetzt ist der Thread fertig");
```
---
# Lost update problem
```java
class Counter {
private int c = 0;
public void decrement() {
c--;
}
}
```
Intern wird `decrement()` auf jeweils drei Operationen abgebildet:
1) Aktuellen Wert von `c` holen
2) Den ermittelten Wert um 1 dekrementieren
3) Das Ergebnis in `c` speichern
---
# Lost update problem
Thread `A` und Thread `B` wollen beide den Zähler dekrementieren. Das kann dazu führen das folgendes passiert:
Ausgangslage: Das Feld `c` hat den Wert `5`.
1) Thread `A`: Aktuellen Wert von `c` holen
2) Thread `B`: Aktuellen Wert von `c` holen
3) Thread `A`: Den ermittelten Wert um 1 dekrementieren. Ergebnis ist `4`.
4) Thread `B`: Den ermittelten Wert um 1 dekrementieren. Ergebnis ist `4`.
5) Thread `A`: Den ermittelten Wert in `c` abspeichern. `c` ist jetzt `4`.
6) Thread `B`: Den ermittelten Wert in `c` abspeichern. `c` ist jetzt `4`.
---
# Mechanismen zur Synchronisation
Um das `Lost update problem` zu beheben müssen wir die Threads miteinander synchronisieren. Die Synchronisation kann auf drei verschiedenen Ebenen passieren:
* Hardware-Ebene
* Betriebssystem-Ebene
* Programiersprachen-Ebene
---
# HW Ebene
Durch den HW-Befehl `SWAP(a,b)`, welcher unteilbar die Werte von zwei Variablen vertauscht, kann eine Synchronisation mit aktivem Warten durchgeführt werden.
```java
int c = 1; //gemeinsame Variable
int i = 0; //prozesslokale Variable
do {
SWAP(c,i)
} while (i == 0)
// Kritischer Abschnitt
SWAP(c,i);
```
Damit können wir schon eine Synchronisation durchführen. Leider basiert die Lösung aber auf aktivem Warten, was nicht perfomant ist.
---
# Betriebssystem Ebene
In einem Betriebssystem können noch andere Prozess-Operationen durchgeführt werden. Es gibt Operationen mit denen ein Prozess freiwillig seine Rechenzeit abgeben kann und es können Prozesse aufgeweckt werden die weiterarbeiten können.
Das Betriebssystem hat dabei verschiedene Strategien nach denen der nächste Prozess ausgewählt werden kann.
---
# Semaphore
Semaphore bestehen aus eine Zähler und einer Warteschlange. Bei der Initialisierung eines Semaphores übergibt man den Wert des Zählers, die Warteschlange ist zu Beginn leer.
Auf einem Semaphor können zwei Operationen durchgeführt werden:
* **P (passieren)**: Der Zähler wird dekrementiert. Ist er positiv, wird der Prozess in den folgenden Abschnitt gelassen. Ist er kleiner als 0 wird der aufrufende Prozess in die Warteschlange eingereiht.
* **V (freigeben)**: Der Zähler wird inkrementiert. Ist der Zähler jetzt größer oder gleich 0 wird ein Prozess aus der Warteschlange aufgeweckt.
So kann die Vergabe von beschränkten Resourcen geregelt werden. Außerdem kann gegenseitiger Ausschluss sichergestellt werden wenn der Sempaphor einen Anfangszähler von 1 hat.
---
# Monitore
Monitore sind ein Bestandteil von Programmiersprachen und ermöglichen gegenseitigen Ausschluss. Idee ist es, dass zusammenhängende Daten **einen** Monitor haben. Im Monitor darf dann immer nur ein Prozess aktiv sein.
In Java besitzt jedes Objekt einen eigenen Monitor. Mit dem Schlüsselwort `synchronized` wird signalisiert, dass ein Block von dem Monitor überwacht werden soll. Ist ein Thread in einem solchen Block sorgt der Monitor dafür, dass kein anderer Thread den Block betritt.
Diese Art von gegeseitigem Ausschluss ist schnell implementiert, kann aber dazu führen dass mehr synchronisiert wird als nötig.
---
# Monitor Deklaration
Für eine ganze Methode.
```java
public synchronized void ausschlussMethode() {
// Kritischer Abschnitt
}
```
Für einen Block.
```java
public void ausschlussBlock() {
synchronized(this) {
// Kritischer Abschnitt
}
}
```
---
# Benachrichtigung anderer Threads
Innerhalb eines Monitors können Threads miteinander interagieren. Innerhalb eines Monitors können folgende Methoden genutzt werden:
* **`wait()`**: Monitor freigeben und in `wait`-Warteschlange warten.
* **`notify()`**: Einen beliebigen Thread in der `wait`-Warteschlange wecken.
* **`notifyAll()`**: Alle Threads in `wait`- Warteschlange wecken.
---
# Komplexität
Nebenläufigkeit kann unter Umständen sehr kompliziert werden. Deswegen sollte es nur verwendet werden wenn es wirklich nötig ist.

93
oo_design.md Normal file
View File

@ -0,0 +1,93 @@
<!--
title: Object Orientated Design
description: Folien für Object Orientated Design in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Objektorientierter Entwurf
---
# Grundlagen
Software verändert sich regelmäßig. Diese Änderungen sollten sich so einfach wie möglich umsetzen lassen. Dabei hilft ein guter Objektorientierter Entwurf.
---
# Zuständigkeiten
Ein Objekt in der Objektorientierung soll immer für genau eine Aufgabe verantwortlich sein (engl. "Seperation of Concerns").
---
# Kopplung
Die Abhängigkeiten zwischen den unterschiedlichen Objekten soll so gering wie möglich sein. Dabei helfen vor allem Interfaces. Es gibt zwei Arten von Kopplung auf die wir achten müssen:
* Explizite Kopplung: Sind zur Übersetzungszeit klar (Methodenaufrufe etc.).
* Implizite Kopplung: Es wird sich auf Interna verlassen die nirgendwo spezifiziert sind (z.B. Sortierung).
---
# Zyklenvermeidung
Es sollte unter den Objekten keine zyklischen Abhängigkeiten geben. Stattdessen sollte eine klare Hierarchie der Klassen bestehen.
---
# Law of Demeter
"Talk to friends not to strangers"
Eine Methode `f` in Klasse `C` sollte nur Methoden aufrufen aus:
* `C`
* Objekte die von `f` erzeugt werden
* Objekte die `f` als Paramter übergeben werden
* Exemplarvariablen von `C`
Vermieden werden sollen sind lange Aufrufketten wie man das in Java häufig sieht.
---
# Kohäsion
Ergänzend zu den Zuständigkeiten. Die Kohäsion ist der Grad der Aufgaben die eine Softwareeinheit erfüllt. Bei hoher Kohäsion ist ein Objekt genau für eine Aufgabe zuständig.
---
# Geeignete Bezeichner
Konkrete Klasse sollten durch ein Substantiv benennbar sein. Methoden sollten durch ein treffendes Verb benennbar sein. Die Bezeichner sollten konsistent im ganzen System sein.
---
# Don't repeat yoursef (DRY)
Quelltext sollte nicht an mehreren Stellen eines Systems identisch vorhanden sein. Das ist ein Zeichen von schlechten Code.
---
# Gottklassen
Beinhaltet eine Klasse plötzlich 90% des Quelltextes dann ist das ein Anti-Pattern (oder Code-Smell). Eine solche "Gottklasse" ist ein Zeichen für einen schlechten Softwareentwurf, da wir niedrige Kohäsion haben.
---
# SOLID
* SRP: Single Responsibility Principle
* Hohe Kohäsion
* OCP: Open Closed Principle
* Open for Extension/Closed for Modification -> Vertrauen in Code steigt
* LSP: Liskov Substitution Principle
* Eine Subklasse soll immer Ersatz für ihre Superklasse sein
* ISP: Interface Segregation Principle
* Ein Klient sollte nicht gezwungen sein von Methoden abzuhänge, die er nicht benutzt
* DIP: Dependency Inversion Principle
* Reduzierte Kopplung: Man sollte niemals von etwas konkreten abhängen sondern immer von Interfaces
---
# Kein Code < Schlechter Code

View File

@ -1,7 +1,7 @@
<!--
title: Termin 3
description: Folien für den ersten Termin in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

View File

@ -1,7 +1,7 @@
<!--
title: Polymorphie und Vererbung
description: Folien für Polymorphie und Vererbung in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

View File

@ -1,7 +1,7 @@
<!--
title: Reflections
description: Folien für Reflections in Programmieren 2
url: https://git.haw-hamburg.de/pm2-tutorium/slides
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->

51
streams.md Normal file
View File

@ -0,0 +1,51 @@
<!--
title: Streams
description: Folien für Streams in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Streams
Erleichtert das Verarbeiten von Sammlungen aus den Collection Framework.
---
# Grundlagen
Die [Stream-API](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html) bietet Higher Order Functions (HOF) die auf Collections arbeiten. Dazu zählen:
* filter
* map
* fold
Die Verarbeitung erfolgt in drei Schritten: Erzeugung des Streams, Verarbeitung des Streams und zum Schluss Terminieren des Streams.
---
# Beispiel
```java
List<String> liste = new ArrayList<String>();
liste.addAll("was", "geht", "ab", "?");
int laenge = liste.stream().map(text -> text.length()).reduce(0, Integer::sum);
List<String> nurWoerter = liste.stream()
.filter(s -> s.matches("[a-zA-Z]"))
.collect(Collectors.toList());
int nurLangeWoerterLaenge = liste.stream()
.filter(s -> s.matches("[a-zA-Z]"))
.filter(s -> s.length() >= 3)
.map(s -> s.length())
.reduce(0, Integer::sum)
```
[`Stream:reduce(Binary)`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-T-java.util.function.BinaryOperator-)
---
# Aufgabe
1) Berechne in `SummiererWerkzeug.setzeSumme()` die Summe der einzelnen Zähler mithilfe von Streams.

0
test Normal file
View File

75
wam-ansatz.md Normal file
View File

@ -0,0 +1,75 @@
<!--
title: Werzeug-Material-Ansatz
description: Folien für Werkzeug Material Ansatz in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Werzeug & Material Ansatz
---
# Grundlagen
Gibt Entwurfsregeln zum entwerfen von interaktiven Softwaresystemen vor. Die Klassen werden aufgeteilt in vier Elementtypen:
* **Materialien** : Anwendungsbezogene Gegenstände
* **Fachwerte** : Anwendungsbezogene unveränderliche Werte
* **Werkzeuge** : Grafische Benutzeroberfläche zum Bearbeiten von Materialien
* **Services** : Materialübergreifende fachliche Dienstleistungen
---
# Materialien
Gegenstände aus der Anwendungsdomäne mit denen gearbeitet wird. Müssen keine materiellen Gegenstände sein.
Darf zugreifen auf:
* Andere Materialien
* Fachwerte
Beispiel: Film, Abrechnung, ...
---
# Fachwerte
Unveränderliche Werte aus der Anwendungsdomäne. Es gibt einen Fachwert nur genau einmal.
Darf auf keine anderen Elemente zugreifen.
Beispiel: Zeit, Geldbetrag, ...
---
# Services
Bieten Dienstleistungen an die im gesamten System zur Verfügung stehen sollen. Es gibt immer nur ein Serviceexemplar für einen Servicetypen.
Darf zugreifen auf:
* Andere Services
* Materialien
* Fachwerte
Beispiel: Datenbankservice, Kundenstammservice, ...
---
# Werkzeug
Bieten Möglichkeiten zur Benutzerinteraktion. Sollten möglichst eine klare Aufgabe übernehmen. Häufig werden Werzeuge in eine UI- und Werkzeugklasse aufgeteilt.
Darf zugreifen auf:
* Andere Werkzeuge
* Services
* Materialien
* Fachwerte
---
# Aufgabe
* Führe einen Confirmation-Dialog ein, der verhindern soll, dass der Benutzer versehentlich den Zähler zurücksetzt. Dafür kann zum Beispiel **Alert** aus JavaFX genutzt werden.

33
werttypen.md Normal file
View File

@ -0,0 +1,33 @@
<!--
title: Werttypen
description: Folien für Werttypen in Programmieren 2
url: https://git.henriburau.de/tutorien/programmieren-2
header: Programmieren 2 **Tutorium**
footer: Henri Burau
-->
# Werttypen
---
# Grundlagen
Es gibt Typen in einer Anwendungsdomäne die einen Wert darstellen der unveränderbar ist und auch nicht doppelt existieren darf. Werttypen bilden dies ab.
Beispiel:
- Kontonummer
- Datum
- Geldbetrag
---
# WAM-Ansatz
In dem WAM-Ansatz bilden die Werttypen die kleinste Einheit.
---
# Aufgabe
1) Schaffe einen neuen Werttypen `Zaehlerstand` und integriere ihn in die Klasse `Zaehler`