Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a446b4058 | |||
| 7c893cf79c | |||
| f6d3032e74 | |||
| e16988cfcd | |||
| d2aa79ac9e | |||
| c63851ddb9 | |||
| ade9c90265 | |||
| 71799703fe | |||
| 3968c9f8c2 | |||
| 98314fc5ee | |||
| f21087b791 | |||
| a062672e2f | |||
| af3772f76d | |||
| 02233fa5ec | |||
| f8c3edb91d | |||
| e4d91c1794 | |||
| efafd8f037 | |||
| 667e7fabda | |||
| a698803b82 | |||
| 5544e16d56 | |||
| 2869c0021c | |||
| 13670ef4b2 | |||
| 0ab45177dc | |||
| beb849929a | |||
| 50b4f8ffcf | |||
| a8a15eb9d3 |
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
title: Termin 1
|
title: Termin 1
|
||||||
description: Folien für den ersten Termin in Programmieren 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**
|
header: Programmieren 2 **Tutorium**
|
||||||
footer: Henri Burau
|
footer: Henri Burau
|
||||||
-->
|
-->
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
title: Termin 2
|
title: Termin 2
|
||||||
description: Folien für den ersten Termin in Programmieren 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**
|
header: Programmieren 2 **Tutorium**
|
||||||
footer: Henri Burau
|
footer: Henri Burau
|
||||||
-->
|
-->
|
||||||
|
|||||||
34
03-termin.md
Normal file
34
03-termin.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!--
|
||||||
|
title: Termin 3
|
||||||
|
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 3
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Fragen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Links
|
||||||
|
[https://git.haw-hamburg.de/pm2-tutorium](https://git.haw-hamburg.de/pm2-tutorium)
|
||||||
|
- Aufgaben
|
||||||
|
- Tutoriumsfolien
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Plan für heute
|
||||||
|
|
||||||
|
Level 5 Themen:
|
||||||
|
|
||||||
|
- Testen und Asserts
|
||||||
|
- Polymorphie und Vererbung
|
||||||
|
- Generizität
|
||||||
|
- Reflections
|
||||||
|
- **Implementationsvererbung**
|
||||||
|
- **Exceptions**
|
||||||
|
- **Module**
|
||||||
29
04-termin.md
Normal file
29
04-termin.md
Normal 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
31
05-termin.md
Normal 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
31
06-termin.md
Normal 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
40
07-termin.md
Normal 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
39
08-termin.md
Normal 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
39
09-termin.md
Normal 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
69
10-termin.md
Normal 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.
|
||||||
99
abstract.md
Normal file
99
abstract.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<!--
|
||||||
|
title: Abstrakte Klasse
|
||||||
|
description: Folien für abstrakte Klassen in Programmieren 2
|
||||||
|
url: https://git.henriburau.de/tutorien/programmieren-2
|
||||||
|
header: Programmieren 2 **Tutorium**
|
||||||
|
footer: Henri Burau
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Abstrakte Klassen
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Abstrakte Klassen
|
||||||
|
|
||||||
|
In abstrakten Klassen können Operationen **ohne** eine Implementation deklariert werden.
|
||||||
|
|
||||||
|
```java
|
||||||
|
abstract double gibFlaeche();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Abstrakte Klassen
|
||||||
|
|
||||||
|
Eine Klasse mit mindestens einer abstrakten Methode muss abstrakt sein.
|
||||||
|
|
||||||
|
Es können keine Instanzen einer abstrakten Klasse erzeugt werden.
|
||||||
|
|
||||||
|
```java
|
||||||
|
abstract class Form
|
||||||
|
{
|
||||||
|
abstract double gibFlaeche();
|
||||||
|
|
||||||
|
String toString()
|
||||||
|
{
|
||||||
|
return "Form";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Benutzung
|
||||||
|
|
||||||
|
Es können keine Instanzen einer abstrakten Klasse erzeugt werden. Trotzdem definieren die abstrakten Klassen einen Typ.
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Deklaration
|
||||||
|
class Kreis extends Form {
|
||||||
|
private double _radius;
|
||||||
|
|
||||||
|
Circle(double rad) {radius = rad;}
|
||||||
|
|
||||||
|
double gibFlaeche(){
|
||||||
|
return 3.14 * radius * radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benutzung
|
||||||
|
Form form1 = new Kreis(4.5);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Verwendung
|
||||||
|
|
||||||
|
Abstrakte Klassen werden immer benutzt wenn Code wiederverwendet werden soll, aber nicht alle Details bekannt sind. Dabei wird häufig das Prinzip der Schablonen- und Einschubmethoden genutzt.
|
||||||
|
|
||||||
|
```java
|
||||||
|
abstract class DreidimensionaleForm {
|
||||||
|
private double _hoehe;
|
||||||
|
|
||||||
|
abstract double gibFlaeche();
|
||||||
|
|
||||||
|
double gibVolumen() {
|
||||||
|
return gibFlaeche() * _hoehe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Welche Methode ist die Einschubmethode und welche die Schablonenmethode?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Übung
|
||||||
|
|
||||||
|
1) Müssen alle abstrakten Methoden eine abstrakten Klasse in einer Subklasse implementiert werden?
|
||||||
|
* 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 `public`, `protected` oder `package private` sind.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
4) Ändere die Klasse `Animal` zu einer abstrakten Klasse. Alle Methoden die bei `Sheep` und `Cow` gleich sind müssen nicht abstrakt sein. Füge aber eine abstrakte Methode `String makeNoise()` ein. Ändere den Code and den richtigen Stellen ab.
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
title: Assertions
|
title: Assertions
|
||||||
description: Folien für Assertions in Programmieren 2
|
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**
|
header: Programmieren 2 **Tutorium**
|
||||||
footer: Henri Burau
|
footer: Henri Burau
|
||||||
-->
|
-->
|
||||||
|
|||||||
12
deploy.yml
12
deploy.yml
@ -1,9 +1,10 @@
|
|||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
kubernetes.io/tls-acme: "true"
|
kubernetes.io/tls-acme: "true"
|
||||||
kubernetes.io/ingress.class: "nginx"
|
kubernetes.io/ingress.class: "nginx"
|
||||||
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||||
name: slides-ingress
|
name: slides-ingress
|
||||||
spec:
|
spec:
|
||||||
tls:
|
tls:
|
||||||
@ -15,9 +16,12 @@ spec:
|
|||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
backend:
|
backend:
|
||||||
serviceName: slides
|
service:
|
||||||
servicePort: 80
|
name: slides
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -56,7 +60,7 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
- name: slides-deploy
|
- name: pull-secret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
37
entwurfsmuster.md
Normal file
37
entwurfsmuster.md
Normal 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."
|
||||||
|
|
||||||
|

|
||||||
|
*Bildquelle: [Philipp Hauer](https://www.philipphauer.de/study/se/design-pattern/observer.php)*
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Observer Implementation
|
||||||
|
|
||||||
|

|
||||||
87
exceptions.md
Normal file
87
exceptions.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<!--
|
||||||
|
title: Assertions
|
||||||
|
description: Folien für Assertions in Programmieren 2
|
||||||
|
url: https://git.henriburau.de/tutorien/programmieren-2
|
||||||
|
header: Programmieren 2 **Tutorium**
|
||||||
|
footer: Henri Burau
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Exceptions
|
||||||
|
|
||||||
|
Erlauben es mit Fehlersituationen in einem Programm umzugehen. Es gibt zwei mögliche Fehlerarten:
|
||||||
|
|
||||||
|
1) **Entwicklungsfehler**
|
||||||
|
Vermeidbare Fehler die während der Entwicklung auftreten. Können gut durch Tests aufgedeckt werden und brauchen keine explizite Fehlerbehandlung.
|
||||||
|
*Beispiel*: Ungültiger Arrayindex, Teilen durch 0
|
||||||
|
|
||||||
|
2) **Umgebungsfehler**
|
||||||
|
Unvermeidbare Fehler die durch die Programmumgebung ausgelöst werden. Diese Fehlerart benötigt eine Fehlerbehandlung.
|
||||||
|
*Beispiel*: Keine Internetverbindung, Zu wenig Festplattenspeicher
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hierarchie
|
||||||
|
|
||||||
|
Exceptions sind Objekte die von `Exception` oder `RuntimeException` erben.
|
||||||
|
|
||||||
|
[](https://mermaid-js.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiY2xhc3NEaWFncmFtXG4gICAgVGhyb3dhYmxlIDx8LS0gRXhjZXB0aW9uXG4gICAgVGhyb3dhYmxlIDx8LS0gRXJyb3JcbiAgICBFeGNlcHRpb24gPHwtLSBSdW50aW1lRXhjZXB0aW9uIiwibWVybWFpZCI6eyJ0aGVtZSI6ImRlZmF1bHQifSwidXBkYXRlRWRpdG9yIjpmYWxzZX0)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Ungeprüfte Exceptions
|
||||||
|
|
||||||
|
Erben von `RuntimeException` und müssen nicht explizit behandelt werden.
|
||||||
|
|
||||||
|
```java
|
||||||
|
Dreieck dreieck = null;
|
||||||
|
double flaeche = dreieck.gibFlaeche();
|
||||||
|
// Programm wird beendet mit NullPointerException
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
# Geprüfte Exceptions
|
||||||
|
|
||||||
|
Erben von `Exception` und müssen explizit behandelt werden.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.print("Bitte Alter eingeben: ");
|
||||||
|
try {
|
||||||
|
Scanner sc = new Scanner(System.in);
|
||||||
|
String name = sc.nextLine();
|
||||||
|
int alter = Integer.parseInt(name); // Wirft ggf. NumberFormatException
|
||||||
|
}
|
||||||
|
catch(NumberFormatException e) {
|
||||||
|
System.out.println("Das war kein gültiges Alter!");
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
sc.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
# Exceptions werfen
|
||||||
|
|
||||||
|
Exceptions werden mit dem Schlüsselwort `throw` geworfen. Wird in einer Methode eine geprüfte Exception nicht behandelt, muss dies in dem Methodenkopf mithilfe von `throws` deklariert werden.
|
||||||
|
|
||||||
|
```java
|
||||||
|
public void pingServer(String serverUrl) throws ConnectException
|
||||||
|
{
|
||||||
|
Server server = connectToServer(serverUrl);
|
||||||
|
if(server == null)
|
||||||
|
{
|
||||||
|
throw new ConnectException("Can't connect to server");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
# Übung
|
||||||
|
|
||||||
|
1) Wann werden geprüfte Exceptions eingesetzt und wann ungeprüfte?
|
||||||
|
* Geprüfte Exceptions bei Umgebungsfehlern, Ungeprüfte Exceptions bei Entwicklungsfehlern
|
||||||
|
|
||||||
|
2) Wie kann eine geprüfte Exception beim Auftreten an den Klienten weitergeleitet werden?
|
||||||
|
* In den Methodenkopf `throws` reinschreiben
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
title: Generizität
|
title: Generizität
|
||||||
description: Folien für Generizität in Programmieren 2
|
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**
|
header: Programmieren 2 **Tutorium**
|
||||||
footer: Henri Burau
|
footer: Henri Burau
|
||||||
-->
|
-->
|
||||||
@ -93,7 +93,7 @@ Beschränkt den Wildcard Typen nach unten. Dafür wird das Schlüsselwort ``supe
|
|||||||
class IntegerSammler {
|
class IntegerSammler {
|
||||||
public void schreib(List<? super Integer> liste) {
|
public void schreib(List<? super Integer> liste) {
|
||||||
for (int i = 0; i <= 10; i++) {
|
for (int i = 0; i <= 10; i++) {
|
||||||
System.out.println(i);
|
liste.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
73
lambdas.md
Normal file
73
lambdas.md
Normal 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
254
nebenlaeufigkeit.md
Normal 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
93
oo_design.md
Normal 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
|
||||||
91
packages.md
Normal file
91
packages.md
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<!--
|
||||||
|
title: Termin 3
|
||||||
|
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
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Module
|
||||||
|
|
||||||
|
Grundlegendes Konzept in der Programmierung zur Organisation von Programmcode.
|
||||||
|
|
||||||
|
Module kapseln Implementationen und exportieren eine Schnittstelle mit Operationen, Typen und Konstanten. Dies kann explizit durch die Java 9 Modules geschehen oder implizit durch Zugriffsmodifikatoren.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Geschachtelte Klassen
|
||||||
|
|
||||||
|
Erlaubt das Verstecken von Hilfsklassen.
|
||||||
|
|
||||||
|
```java
|
||||||
|
class Dreieck {
|
||||||
|
private Koordinate _a;
|
||||||
|
private Koordinate _b;
|
||||||
|
private Koordinate _c;
|
||||||
|
|
||||||
|
private class Koordinate
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Pakete
|
||||||
|
|
||||||
|
Ermöglichen Namensräume von zusammengehörigen Klassen. Klassen und Interfaces sind nur sichtbar wenn sie mit dem Schlüsselwort `public` deklariert wurden.
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Dreieck.java
|
||||||
|
package formen;
|
||||||
|
public class Dreieck {
|
||||||
|
private Koordinate _a;
|
||||||
|
private Koordinate _b;
|
||||||
|
private Koordinate _c;
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
// Koordinate.java
|
||||||
|
package formen;
|
||||||
|
class Koordinate
|
||||||
|
{
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Imports
|
||||||
|
|
||||||
|
Möchte man Klassen und Interfaces aus einem anderen Paket nutzen dann müssen diese importiert werden. Um eine Grundfunktionalität von Java zu gewährleisten wird das Paket [`java.lang`](https://docs.oracle.com/javase/8/docs/api/java/lang/package-summary.html) immer importiert.
|
||||||
|
|
||||||
|
```java
|
||||||
|
import java.util.List; // Nur List
|
||||||
|
import java.util.*; // Alle Klassen und Interfaces aus java.util
|
||||||
|
|
||||||
|
import static org.junit.Assert.*; // Statischer Import der Asserts
|
||||||
|
|
||||||
|
import java.lang.*; // Default Import der immer gemacht wird
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Sichtbarkeiten
|
||||||
|
|
||||||
|
Sichtbarkeiten von Methoden, Konstruktoren und Feldern:
|
||||||
|
|
||||||
|
* **public**: Sichtbar innerhalb und außerhalb des eigenen Pakets
|
||||||
|
* **protected**: Sichtbar innerhalb des Pakets und für erbende Klassen
|
||||||
|
* **package-private**: Sichtbar innerhalb des Pakets
|
||||||
|
* **private**: Nur sichtbar innerhalb der Klasse
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Übung
|
||||||
|
|
||||||
|
1) Durch welches Schlüsselwort wird der Modifikator `package-private` genutzt?
|
||||||
|
* Durch die Verwendung von keinem Schlüsselwort als Modifikator
|
||||||
|
|
||||||
|
2) Wie sollten Pakete benannt werden?
|
||||||
|
* Umgedrehte Domain: `de.henriburau.meineKlassen`
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
title: Polymorphie und Vererbung
|
title: Polymorphie und Vererbung
|
||||||
description: Folien für Polymorphie und Vererbung in Programmieren 2
|
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**
|
header: Programmieren 2 **Tutorium**
|
||||||
footer: Henri Burau
|
footer: Henri Burau
|
||||||
-->
|
-->
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<!--
|
<!--
|
||||||
title: Reflections
|
title: Reflections
|
||||||
description: Folien für Reflections in Programmieren 2
|
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**
|
header: Programmieren 2 **Tutorium**
|
||||||
footer: Henri Burau
|
footer: Henri Burau
|
||||||
-->
|
-->
|
||||||
|
|||||||
51
streams.md
Normal file
51
streams.md
Normal 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.
|
||||||
75
wam-ansatz.md
Normal file
75
wam-ansatz.md
Normal 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
33
werttypen.md
Normal 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`
|
||||||
Reference in New Issue
Block a user