diff --git a/admin/exams.md b/admin/exams.md index bce6b8a8b..369b9021e 100644 --- a/admin/exams.md +++ b/admin/exams.md @@ -2,7 +2,7 @@ title: "Prüfungsvorbereitung" author: "Carsten Gips (HSBI)" tldr: | - ### Durchführung: Präsenz oder Open-Book (je nach Corona-Lage) + **Durchführung: Präsenz oder Open-Book (je nach Corona-Lage)** Die Klausur wird dieses Semester elektronisch stattfinden. Dazu werden wir den Prüfungs-ILIAS der HSBI nutzen. @@ -22,13 +22,13 @@ tldr: | Die Entscheidung über die konkrete Durchführung wird spätestens zwei Wochen vor der Prüfung getroffen und Ihnen per EMail über das LSF mitgeteilt. - ### Ablauf der Klausur + **Ablauf der Klausur** Die Prüfung (das ILIAS-Objekt) selbst schalte ich erst zum Start der Prüfung online. Bei der Durchführung als Open-Book-Ausarbeitung wird parallel zur Prüfung eine Zoom-Sitzung laufen, in der Sie Fragen stellen können. - ### Hilfsmittel und Themen + **Hilfsmittel und Themen** Bei der Durchführung in Präsenz am Campus Minden ist ein Spickzettel (DIN A4, beidseitig beschrieben) als Hilfsmittel zugelassen. @@ -56,9 +56,9 @@ attachments: --- -## Elektronische Klausur: Termin, Materialien +# Elektronische Klausur: Termin, Materialien -### Termin +## Termin Die schriftliche Prüfung erfolgt durch eine Klausur, die als digitale Prüfung auf einem Prüfungs-ILIAS durchgeführt wird. @@ -75,7 +75,7 @@ Dauer jeweils 90 Minuten. * Die konkrete Durchführungsform [(in Präsenz am Campus Minden oder im Home-Office)]{.notes} wird Ihnen [spätestens]{.notes} zwei Wochen vor der Prüfung über das LSF bekanntgegeben -### Zugelassene Hilfsmittel +## Zugelassene Hilfsmittel ::: {.details title="Präsenz (in Minden)"} @@ -102,12 +102,12 @@ Sie alle Unterlagen benutzen. ::: -### Einsicht +## Einsicht * Prüfungseinsicht: Zeitnah; Bekanntgabe per Mail -## Technische Vorbereitungen +# Technische Vorbereitungen ::: {.details title="Präsenz (in Minden)"} @@ -175,7 +175,7 @@ für Sie vorbereitet sein. ::: -## Bearbeitung des E-Assessment +# Bearbeitung des E-Assessment 1. Lesen Sie sich die Hinweise auf der Startseite durch @@ -207,7 +207,7 @@ für Sie vorbereitet sein. Täuschungsversuch gewertet werden, vgl. RPO §22a (4))]{.notes} -## Fragetypen-Demo +# Fragetypen-Demo In Ihrem ILIAS-Kurs finden Sie eine [**Fragetypen-Demo**](https://www.hsbi.de/elearning/goto.php?target=tst_1352273&client_id=FH-Bielefeld) @@ -216,7 +216,7 @@ Sie sich die Kommentare bei den einzelnen Aufgaben an. Sie können die Demo bei wiederholen. -## Hinweise zu den Inhalten +# Hinweise zu den Inhalten * Klausurrelevant: Vorlesung und Praktikum * Für Verständnis u.U. hilfreich: Studium der vertiefenden Literaturangaben @@ -234,9 +234,9 @@ wiederholen. ::: -## Beispiele für mögliche Fragen +# Beispiele für mögliche Fragen -### Vererbung und Polymorphie +## Vererbung und Polymorphie Betrachten Sie den folgenden Java-Code: @@ -261,7 +261,7 @@ Geben Sie alle Ausgaben, die das obige Programm produziert, an. Begründen Sie Ihre Antwort kurz und stichhaltig (für *jede* Ausgabe!). Was geschieht, bzw. wieso kommt es zu der jeweiligen Ausgabe? -### Multithreading und Synchronisierung +## Multithreading und Synchronisierung ```java public class StaffelKaputt extends Thread { @@ -289,12 +289,12 @@ Welche Ausgabe erwarten Sie (angenommen, das Programm wäre fehlerfrei; eine mögliche Variante reicht)? Welche Ausgabe erhalten Sie stattdessen? Korrigieren Sie den Fehler. -### Reguläre Ausdrücke +## Reguläre Ausdrücke Auf welche Strings passt (im Sinne von "match") der folgende reguläre Ausdruck: `\s*([a-zA-Z0-9_.\-]+)\s*=\s*(-?\d+\.?\d*)\s;?\s*` -### Versionieren mit Git +## Versionieren mit Git * Erklären Sie, wie man mit Git die Unterschiede zwischen zwei bestimmten Versionsständen einer Datei herausfindet. @@ -316,7 +316,7 @@ Ausdruck: `\s*([a-zA-Z0-9_.\-]+)\s*=\s*(-?\d+\.?\d*)\s;?\s*` * Was würde `git diff` jeweils nach Schritt 2 anzeigen? -### Kommandozeilenparameter +## Kommandozeilenparameter Schreiben Sie ein Programm, welches auf zwei Kommandozeilenparameter reagieren kann. Die erkannten Parameter sollen auf der Konsole ausgegeben werden. Nutzen @@ -330,7 +330,7 @@ Sie Apache Commons CLI (API siehe Anhang). * Die Parameter können in unterschiedlicher Reihenfolge auftreten. * Es kann auch nur ein Parameter angegeben werden. -### Build mit Ant +## Build mit Ant * Was ist der Unterschied zwischen Ant-Targets und Ant-Tasks? * Wie kann man Ant-Properties von außen (beim Aufruf) setzen? @@ -342,7 +342,7 @@ Sie Apache Commons CLI (API siehe Anhang). * Schreiben Sie Ant-Targets, mit denen Sie JUnit-Testfälle ausführen und auswerten können. -### Generics +## Generics Was kommt hier raus? Und warum? @@ -363,7 +363,7 @@ public class X { } ``` -### Logging +## Logging Erklären Sie den Code. Was passiert? @@ -391,7 +391,7 @@ public class MoreLogging { } ``` -### Methodenreferenzen +## Methodenreferenzen * Was bedeutet der folgende Code? diff --git a/homework/b01.md b/homework/b01.md index cdbc72556..fb8063048 100644 --- a/homework/b01.md +++ b/homework/b01.md @@ -13,7 +13,7 @@ der LV "Programmieren 1".* Implementieren Sie in Java das Spiel [Hangman]. -## A01.1: Installation JDK und IDE, Deaktivierung AI-Support +# A01.1: Installation JDK und IDE, Deaktivierung AI-Support Sie benötigen für die Bearbeitung der Übungsaufgaben ein *Java Development Kit* (JDK). Wir verwenden in der Lehrveranstaltung "Programmieren 2" aus verschiedenen Gründen die *Long-Term @@ -34,7 +34,7 @@ sämtliche KI-Unterstützung wie beispielsweise Copilot, JetBrains AI Assistant, CodeGPT, Codeium, Tabnine, Windsurf, ... (Liste nicht vollständig) für die Bearbeitung der Übungsaufgaben in dieser Lehrveranstaltung ab. -## A01.2: Anlegen eines Java-Projektes +# A01.2: Anlegen eines Java-Projektes Legen Sie für die Bearbeitung der Aufgabe ein neues Java-Projekt in Ihrer IDE an. Achten Sie bitte darauf, dass im Projektpfad **keine Leerzeichen** und **keine Sonderzeichen** (Umlaute @@ -56,7 +56,7 @@ Testen Sie bitte die genutzte Java-Version: Korrigieren Sie Ihr Setup, wenn Sie andere Ausgaben erhalten. -## A01.3: Übersetzen und Starten und Debuggen von Programmen +# A01.3: Übersetzen und Starten und Debuggen von Programmen Erstellen Sie in Ihrem neuen Projekt die folgende Klasse: @@ -81,7 +81,7 @@ Starten Sie das obige Programm im Debug-Modus Ihrer IDE. Halten Sie die Ausführ die nächste Anweisung (das `System.out.println`) aus. Wie beenden Sie das Programm? Demonstrieren Sie das live im Praktikum. -## A01.4: Swing und Java2D +# A01.4: Swing und Java2D Das Spiel soll vollständig über eine in Swing und Java2D realisierte GUI bedient werden: @@ -91,7 +91,7 @@ Das Spiel soll vollständig über eine in Swing und Java2D realisierte GUI bedie 4. Die bisher eingegebenen Buchstaben sollen in der Reihenfolge der Eingabe angezeigt werden. 5. Das Spiel soll per Knopfdruck abgebrochen und neu gestartet werden können. -## A01.5: Einlesen von Textdateien +# A01.5: Einlesen von Textdateien Es soll die Möglichkeit geben, eine Textdatei mit zu ratenden Wörtern einzulesen: @@ -105,11 +105,11 @@ Es soll die Möglichkeit geben, eine Textdatei mit zu ratenden Wörtern einzules 6. Es soll für jedes neue Spiel ein zufälliges Wort aus der Menge der eingelesenen Wörter zum Raten ausgewählt werden. -## A01.6: Dokumentation +# A01.6: Dokumentation Erstellen Sie ein UML-Klassendiagramm für Ihre Lösung. -## A01.7: Fortgeschrittenere Aufgaben +# A01.7: Fortgeschrittenere Aufgaben 1. Heben Sie in der Anzeige der eingegebenen Buchstaben die korrekt geratenen Buchstaben in grüner Farbe hervor. diff --git a/homework/b02.md b/homework/b02.md index 0596bfd02..56289202c 100644 --- a/homework/b02.md +++ b/homework/b02.md @@ -8,9 +8,9 @@ attachments: -## Git +# Git -### A02.1: Git Status erklären +## A02.1: Git Status erklären Betrachten Sie die folgende Ausgabe von `git status` in einer lokalen Workingcopy (*Arbeitskopie*): @@ -35,7 +35,7 @@ Erklären Sie die Ausgabe. Geben Sie eine Befehlssequenz an, mit der Sie nur die Änderungen in `foo.java` committen können. -### A02.2: Git-Spiel +## A02.2: Git-Spiel Klonen Sie die [Vorgaben "Git-Quest"]. Sie finden die Geschichte des Helden Markus im Dungeon.[^1] @@ -71,7 +71,7 @@ Dungeon.[^1] Demonstrieren Sie Ihr Vorgehen im Praktikum jeweils live. -### A02.3: Commit-Meldungen +## A02.3: Commit-Meldungen Gute Commit-Meldungen schreiben erfordert Übung. Schauen Sie sich die beiden Commits [Dungeon-CampusMinden/Dungeon/commit/46530b6] und @@ -80,7 +80,7 @@ Gute Commit-Meldungen schreiben erfordert Übung. Schauen Sie sich die beiden Co Diskutieren Sie jeweils, was Ihnen an den Commits auffällt: Was gefällt Ihnen, was stört Sie? Schlagen Sie Verbesserungen vor. -## A02.4: Gradle +# A02.4: Gradle Folgen Sie der Anleitung auf [gradle.org] und installieren Sie Gradle auf Ihrem Rechner. Legen Sie in der Konsole ein neues Gradle-Projekt für eine Java-Applikation an (ohne IDE!). Das @@ -98,7 +98,7 @@ Aufgaben diese Abschnitte jeweils erfüllen. Gehen Sie dabei im *Detail* auf das Machen Sie sich Notizen, welche Sie im Praktikum nutzen dürfen, um dort das Buildskript zu erklären. -## A02.5: Calculator: Anonyme Klassen und Lambda-Ausdrücke +# A02.5: Calculator: Anonyme Klassen und Lambda-Ausdrücke Klonen Sie die [Vorgaben "Calculator"] und laden Sie das Projekt als Gradle-Projekt in Ihre IDE. diff --git a/homework/b03.md b/homework/b03.md index 51ecef10c..537d08834 100644 --- a/homework/b03.md +++ b/homework/b03.md @@ -8,7 +8,7 @@ attachments: -## A03.1: Git-Spiel +# A03.1: Git-Spiel Betrachten Sie erneut die [Vorgaben zur "Git-Quest"]. Die Geschichte des Helden Markus findet im `master`-Branch kein Ende, sondern erst im Hilfsbranch `end`. @@ -34,12 +34,12 @@ einem frischen Klon der Vorgaben. Was beobachten Sie jeweils? Erklären Sie Ihre Beobachtungen. Wenn es Konflikte gibt: Wie lösen Sie diese auf? Demonstrieren Sie das Vorgehen im Praktikum live. -## LSF-Contact +# LSF-Contact Betrachten Sie die [Vorgaben "LSF-Contact"]. Klonen Sie das Repo und laden Sie das Projekt als Gradle-Projekt in Ihre IDE. -### A03.2: Methoden-Referenzen +## A03.2: Methoden-Referenzen Sie finden im Package `lsfcontact` eine Klasse `Student`. Jede Instanz dieser Klasse hat mindestens einen Namen (`String`), und man kann verschiedene Konktaktmöglichkeiten per Setter @@ -77,7 +77,7 @@ Schaffen Sie es, diese durch Methodenreferenzen zu ersetzen? Achten Sie darauf, alle Schritte nachvollziehbar in Ihrer Arbeitskopie per Git Commit festzuhalten. Demonstrieren Sie dies im Praktikum. -### A03.3: Logging +## A03.3: Logging Bauen Sie für das `LsfContactUtil` ein Logging auf der Basis von `java.util.logging` ein: Jede Benachrichtigung von Studierenden soll in ein gemeinsames CSV-File geloggt werden. Dabei soll diff --git a/homework/b04.md b/homework/b04.md index 64da03fba..51846adbc 100644 --- a/homework/b04.md +++ b/homework/b04.md @@ -14,9 +14,9 @@ Aufgaben in einem öffentlich sichtbaren Git-Repo durchführen sollen. Den Link jeweiligen Lösungs-Repo geben Sie bitte in Ihrem *Post Mortem* mit an. ::: -## Stream-API +# Stream-API -### A04.1: Git: Pull-Requests (und Code-Formatierung und -Dokumentation) +## A04.1: Git: Pull-Requests (und Code-Formatierung und -Dokumentation) Forken Sie das ["Stream-API"]-Repo und erzeugen Sie eine lokale Arbeitskopie von Ihrem Fork. @@ -30,7 +30,7 @@ einen Pull-Request auf **Ihren** eigenen `master`-Branch. Achten Sie darauf, alle Schritte nachvollziehbar in Ihrer Arbeitskopie per Git-Commit festzuhalten. Demonstrieren Sie im Praktikum, wie Sie mit den Pull-Requests arbeiten. -### A04.2: Stream-API: Task I +## A04.2: Stream-API: Task I Betrachten Sie den Branch `task_i`. Sie finden im Package `streamapi` einige Hilfsklassen sowie in der Datei [`Main.java`] einen Starter für diese erste Teilaufgabe. @@ -42,7 +42,7 @@ Schreiben Sie den Body dieser Methode so um, dass die selbe Funktionalität unte [Java-Stream-API] erreicht wird. Bevorzugen Sie dabei nach Möglichkeit Methoden-Referenzen vor Lambda-Ausdrücken. -### A04.3: Stream-API: Task II +## A04.3: Stream-API: Task II Betrachten Sie nun den Branch `task_ii`. Sie finden wieder im Package `streamapi` einige Hilfsklassen sowie in der Datei [`Main.java`][1] einen Starter für diese zweite Teilaufgabe. @@ -57,7 +57,7 @@ Schreiben Sie den Body dieser Methode so um, dass die selbe Funktionalität unte [Java-Stream-API] erreicht wird. Bevorzugen Sie dabei nach Möglichkeit Methoden-Referenzen vor Lambda-Ausdrücken. -### A04.4: Stream-API: Task III +## A04.4: Stream-API: Task III Betrachten Sie nun den Branch `task_iii`. Sie finden wieder im Package `streamapi` einige Hilfsklassen sowie in der Datei [`Main.java`][2] einen Starter für diese dritte Teilaufgabe. @@ -70,7 +70,7 @@ Schreiben Sie den Body dieser Methode so um, dass die selbe Funktionalität unte [Java-Stream-API] erreicht wird. Bevorzugen Sie dabei nach Möglichkeit Methoden-Referenzen vor Lambda-Ausdrücken. -### A04.5: Stream-API: Task IV+V +## A04.5: Stream-API: Task IV+V Betrachten Sie nun den Branch `task_iv_v`. Sie finden wieder im Package `streamapi` einige Hilfsklassen sowie in der Datei [`Main.java`][3] einen Starter für diese vierte Teilaufgabe. @@ -105,11 +105,11 @@ Hilfsklassen sowie in der Datei [`Main.java`][3] einen Starter für diese vierte der [Java-Stream-API] erreicht wird. Bevorzugen Sie dabei nach Möglichkeit Methoden-Referenzen vor Lambda-Ausdrücken. -### A04.6: Record-Klassen +## A04.6: Record-Klassen Machen Sie aus der Klasse `streamapi.Student` eine Record-Klasse. -## A04.7: DevDungeon: Zerbrechende Tiles und Speed Potions (Lambda-Ausdrücke) +# A04.7: DevDungeon: Zerbrechende Tiles und Speed Potions (Lambda-Ausdrücke) Klonen Sie das Projekt [DevDungeon] und laden Sie es in Ihrer IDE als Gradle-Projekt. Betrachten Sie das Sub-Projekt[^1] "devDungeon". Dies ist ein von einem Studierenden diff --git a/homework/b05.md b/homework/b05.md index a98a730a7..30591e89b 100644 --- a/homework/b05.md +++ b/homework/b05.md @@ -8,7 +8,7 @@ attachments: -## A05.1: DevDungeon: Fackeln im Sturm (Streams, Optional) +# A05.1: DevDungeon: Fackeln im Sturm (Streams, Optional) Klonen Sie das Projekt [DevDungeon] und laden Sie es in Ihrer IDE als Gradle-Projekt. Betrachten Sie das Sub-Projekt "devDungeon". Dies ist ein von einem Studierenden ([\@Flamtky]) @@ -41,7 +41,7 @@ Task `devDungeon:runDevDungeon` aus der IDE heraus) starten. Sonderzeichen (Umlaute o.ä.) vorkommen! Dies kann zu seltsamen Fehler führen. Bitte auch darauf achten, dass Sie als JDK ein **Java SE 21 (LTS)** verwenden. -## Katzen-Café +# Katzen-Café Forken Sie das ["Cat-Cafe"]-Repo und erzeugen Sie sich eine lokale Arbeitskopie von Ihrem Fork. @@ -55,7 +55,7 @@ eigenen `master`-Branch. Achten Sie darauf, alle Schritte nachvollziehbar in Ihrer Arbeitskopie per Git-Commit festzuhalten. Demonstrieren Sie im Praktikum, wie Sie mit den Pull-Requests arbeiten. -### A05.2: Code-Analyse +## A05.2: Code-Analyse Analysieren Sie die Modellierung des Binärbaums (`Tree`, `Empty`, `Node`) und erklären Sie die Funktionsweise: @@ -66,7 +66,7 @@ Funktionsweise: `Tree mytree; mytree.stream(). ...` nutzen zu können? - Wie funktioniert der `TreeIterator`? -### A05.3: Optional +## A05.3: Optional Bauen Sie die beiden Methoden `CatCafe#getCatByName` und `CatCafe#getCatByWeight` so um, dass ein passendes `Optional` zurückgeliefert wird. Passen Sie die entsprechenden Methodenaufrufe @@ -75,7 +75,7 @@ in `Main#main` entsprechend an. *Tipp*: Stellen Sie in den beiden Methoden auf die [Java-Stream-API] um, dann ergibt sich die Nutzung von `Optional` fast von selbst. -### A05.4: JUnit +## A05.4: JUnit Erstellen Sie mit JUnit 4 oder 5 mindestens 10 unterschiedliche Testfälle für die Klasse `CatCafe`. @@ -87,7 +87,7 @@ automatisch zur Verfügung. Wenn Sie JUnit4 nutzen möchten, müssten Sie bitte Gradle-Konfiguration entsprechend anpassen. Mit `./gradlew test` können Sie entsprechende Testfälle ausführen. -### A05.5: Visitor-Pattern +## A05.5: Visitor-Pattern Die Klasse `CatCafe` hat eine Methode `CatCafe#accept`, die einen Visitor mit dem parametrischen Typ `TreeVisitor` an das intern genutzte Feld `Tree clowder` diff --git a/homework/b06.md b/homework/b06.md index a28d54bb6..3d8e84a2f 100644 --- a/homework/b06.md +++ b/homework/b06.md @@ -8,8 +8,6 @@ attachments: -## Cycle Chronicles - Forken Sie das ["Cycle Chronicles"]-Repo und erzeugen Sie sich eine lokale Arbeitskopie von Ihrem Fork. @@ -22,7 +20,7 @@ eigenen `master`-Branch. Achten Sie darauf, alle Schritte nachvollziehbar in Ihrer Arbeitskopie per Git-Commit festzuhalten. Demonstrieren Sie im Praktikum, wie Sie mit den Pull-Requests arbeiten. -### A06.1: Analyse: Äquivalenzklassen & Grenzwerte +# A06.1: Analyse: Äquivalenzklassen & Grenzwerte Die Methode `Shop#accept` dient zur Annahme eines neuen Auftrags eines Kunden. @@ -45,7 +43,7 @@ Aufgaben: 2. Erstellen Sie aus den ermittelten ÄK und GW konkrete Testfälle. (**Noch keine Implementierung!**) -### A06.2: Mocking I +# A06.2: Mocking I Implementieren Sie nun die in der vorigen Aufgabe ermittelten Testfälle für die Methode `Shop#accept` mit Hilfe von JUnit (Version 4 oder 5). @@ -68,7 +66,7 @@ JUnit5-Bibliothek automatisch zur Verfügung. Wenn Sie JUnit4 nutzen möchten, m die Gradle-Konfiguration entsprechend anpassen. Mit `./gradlew test` können Sie Ihre Testfälle ausführen. -### A06.3: Mocking II +# A06.3: Mocking II Die Methoden `Shop#repair` und `Shop#deliver` sind auch noch nicht implementiert. Nutzen Sie geeignetes Mocking, um für diese beiden Methoden Tests in JUnit zu implementieren. Begründen @@ -76,7 +74,7 @@ Sie die Anwendung von Mockito. *Hinweis*: Sie *müssen* hier keine ÄK/GW-Analyse machen, können das aber natürlich gern tun. -### A06.4: Record-Klassen +# A06.4: Record-Klassen Die Klasse `Order` ist zwar bisher nur unvollständig implementiert, aber Sie können bereits deutlich erkennen, dass es zwei Attribute geben muss (welche?). @@ -85,7 +83,7 @@ Bauen Sie die Klasse in eine passende Record-Klasse mit den entsprechenden Attri dürfen die beiden Methoden in `Order` auch geeignet "implementieren" und umbenennen - die Umbenennung muss dann aber auch in den Aufrufen in `Shop` und in Ihren JUnit-Tests passieren! -### A06.5: Logging +# A06.5: Logging Bauen Sie für den `Shop` ein Logging auf der Basis von `java.util.logging` ein: Jede Änderung an der Auftrags-Warteschlange `pendingOrders` und auch an der Menge der fertigen Aufträge diff --git a/homework/b07.md b/homework/b07.md index 7b9baba97..606cd9afb 100644 --- a/homework/b07.md +++ b/homework/b07.md @@ -8,7 +8,7 @@ attachments: -## A07.1: Javadoc-Kommentare +# A07.1: Javadoc-Kommentare Gute Javadoc-Kommentare schreiben erfordert Übung. Schauen Sie sich die in Commit [Dungeon-CampusMinden/Dungeon/commit/46530b6] neu hinzugefügte Datei @@ -17,14 +17,14 @@ Gute Javadoc-Kommentare schreiben erfordert Übung. Schauen Sie sich die in Comm Diskutieren Sie jeweils, was Ihnen an der Dokumentation dieser Klasse auffällt: Was gefällt Ihnen, was stört Sie? Schlagen Sie Verbesserungen vor. -## DevDungeon: Illusion Riddle +# DevDungeon: Illusion Riddle Klonen Sie das Projekt [DevDungeon] und laden Sie es in Ihrer IDE als Gradle-Projekt. Betrachten Sie das Sub-Projekt "devDungeon". Dies ist ein von einem Studierenden ([\@Flamtky]) erstelltes Spiel mit mehreren Leveln, in denen Sie spielerisch verschiedene Aufgaben *in-game* und *ex-game* lösen müssen. -### A07.2: DevDungeon: Lösen des Illusion Riddle +## A07.2: DevDungeon: Lösen des Illusion Riddle Starten Sie den DevDungeon mit `./gradlew devDungeon:runDevDungeon`. Spielen Sie sich für diese Aufgabe durch das **dritte Level** ("Illusion Riddle")[^1]. @@ -66,7 +66,7 @@ Task `devDungeon:runDevDungeon` aus der IDE heraus) starten. Sonderzeichen (Umlaute o.ä.) vorkommen! Dies kann zu seltsamen Fehler führen. Bitte auch darauf achten, dass Sie als JDK ein **Java SE 21 (LTS)** verwenden. -### A07.3: DevDungeon: Refactoring der Klasse IllusionRiddleLevel +## A07.3: DevDungeon: Refactoring der Klasse IllusionRiddleLevel Analysieren Sie die Klasse `IllusionRiddleLevel` im Package `level.devlevel`, insbesondere die beiden Methoden `IllusionRiddleLevel#onTick` und `IllusionRiddleLevel#lightTorch`: @@ -89,7 +89,7 @@ beginnen. Leider ist durch die Abhängigkeit zu libGDX und der Game-Loop das Tes Dungeon nicht trivial, so dass Sie hier ausnahmsweise direkt mit dem Refactoring loslegen dürfen und auf das Erstellen einer Testsuite verzichten können. -### A07.4: Protector-Skill für Ihren Hero +## A07.4: Protector-Skill für Ihren Hero Erstellen Sie einen neuen Protector-Skill für den Hero und weisen Sie diesen einer Taste zu. Bei Nutzung des Skills soll ein neues Protector-Monster an einer zufälligen Position in einem @@ -105,7 +105,7 @@ dadurch leichter zum Ausgang des Levels kommen. **Hinweis**: Erinnern Sie sich an die [ECS-Architektur]. Schauen Sie sich u.a. die Factory `HeroFactory` und den `FireballSkill` an. -## A07.5: Refactoring im Bike-Shop +# A07.5: Refactoring im Bike-Shop Forken Sie das [Refactoring]-Repo und erzeugen Sie sich eine lokale Arbeitskopie von Ihrem Fork. Analysieren Sie die Klassen im Package `refactoring`. Sie finden unübersichtlichen und diff --git a/homework/b08.md b/homework/b08.md index 368a6c0d0..7d1d34c29 100644 --- a/homework/b08.md +++ b/homework/b08.md @@ -9,7 +9,7 @@ attachments: -## DevDungeon: Brücken-Troll +# DevDungeon: Brücken-Troll Klonen Sie das Projekt [DevDungeon] und laden Sie es in Ihrer IDE als Gradle-Projekt. Betrachten Sie das Sub-Projekt "devDungeon". Dies ist ein von einem Studierenden ([\@Flamtky]) @@ -43,7 +43,7 @@ Task `devDungeon:runDevDungeon` aus der IDE heraus) starten. Sonderzeichen (Umlaute o.ä.) vorkommen! Dies kann zu seltsamen Fehler führen. Bitte auch darauf achten, dass Sie als JDK ein **Java SE 21 (LTS)** verwenden. -### A08.1: RegExp mit dem Brücken-Troll +## A08.1: RegExp mit dem Brücken-Troll Suchen Sie den Brücken-Troll auf und sprechen Sie ihn an. Er wird Ihnen eine Reihe von Fragen zum Thema reguläre Ausdrücke stellen, die Sie korrekt beantworten müssen. @@ -51,7 +51,7 @@ zum Thema reguläre Ausdrücke stellen, die Sie korrekt beantworten müssen. Machen Sie Screenshots von den Fragen und Ihren Antworten, die Sie im Praktikum vorstellen und diskutieren. -### A08.2: Command-Pattern mit der Klasse *BridgeControlCommand* +## A08.2: Command-Pattern mit der Klasse *BridgeControlCommand* Leider lässt sich der Brücken-Troll offenbar weder durch Diskussion noch durch Kampf besiegen. Aber vielleicht können Sie die Brücke "aufmachen", so dass er in die Tiefe stürzt? Die *Tiles* @@ -71,7 +71,7 @@ Implementieren Sie die beiden Methoden und starten Sie das Spiel erneut. **Hinweis**: Mit der Methode `Game.currentLevel().tileAt()` können Sie auf ein `Tile` an einer bestimmte Koordinate zugreifen. -## A08.3: Syntaxhighlighting mit RegExp +# A08.3: Syntaxhighlighting mit RegExp Klonen Sie die [Vorgaben "Syntax Highlighting"] und laden Sie das Projekt als Gradle-Projekt in Ihre IDE. diff --git a/homework/b09.md b/homework/b09.md index 5e848619c..c91bc68ca 100644 --- a/homework/b09.md +++ b/homework/b09.md @@ -8,13 +8,11 @@ attachments: -## Zoo - Sie finden in den [Vorgaben] im Package `zoo` einige Interfaces und Klassen, mit denen man einen Zoo modellieren kann. Klonen Sie das Vorgabe-Repo und laden Sie das Projekt als Gradle-Projekt in Ihre IDE. -### A09.1: Nicht-generische Klassen +# A09.1: Nicht-generische Klassen Sie finden einige Interfaces, die das Interface `Animal` erweitern, beispielsweise `Fish`, `Reptile`, `Cat`, ... @@ -32,7 +30,7 @@ ein kurzer Name, beispielsweise der Tierklasse, zurückgegeben werden. Sie in Ihren Klassen nicht implementieren. Wir werden später im Semester noch über die sogenannten ["Default-Methoden"] sprechen. -### A09.2: Generische Klassen +# A09.2: Generische Klassen Um Gehege zu modellieren, erstellen Sie in eine generische Klasse `Habitat` mit einer Typ-Variablen. Stellen Sie durch geeignete Beschränkung der Typ-Variablen sicher, dass nur @@ -54,7 +52,7 @@ generischen Klasse `Habitat` an. Dabei sollen in diesen konkreten Gehegen nur je verschiedene Tiere einer "Art" (beispielweise Löwen, Hamster, ...) vorkommen. Fügen Sie einige passende Tiere in die beiden Gehege ein. -### A09.3: Generische Klassen reloaded +# A09.3: Generische Klassen reloaded Für die Repräsentation eines Zoologischen Gartens mit mehreren verschiedenen Gehegen erstellen Sie nun eine generische Klasse `Zoo` mit einer Typ-Variablen. Stellen Sie durch geeignete @@ -76,7 +74,7 @@ eine Ordnung auf den Gehegen. Begründen Sie die Wahl der Datenstruktur. Legen Sie in Ihrer `main()`-Methode einen konkreten Zoo als Instanz der neuen generischen Klasse `Zoo` an. Dieser Zoo soll einige Gehege für verschiedene Tiere beinhalten. -### A09.4: Ableiten nicht-generischer Klassen +# A09.4: Ableiten nicht-generischer Klassen Leiten Sie von `Zoo` eine nicht-generische Klasse `Aquarium` ab. Aquarien können nur mit Gehegen angelegt werden, deren Tiere vom Typ `Fish` (oder abgeleitet) sind. diff --git a/lecture/building/ant.md b/lecture/building/ant.md index d917c9a92..165186002 100644 --- a/lecture/building/ant.md +++ b/lecture/building/ant.md @@ -50,7 +50,7 @@ fhmedia: --- -## Automatisieren von Arbeitsabläufen +# Automatisieren von Arbeitsabläufen ::: center Works on my machine ... @@ -80,7 +80,7 @@ Works on my machine ... ::: -## Aufbau von Ant-Skripten: Projekte und Targets +# Aufbau von Ant-Skripten: Projekte und Targets ```xml @@ -100,7 +100,7 @@ Works on my machine ... ::: -## Aufgaben erledigen: Tasks +# Aufgaben erledigen: Tasks ::: notes * **Tasks**: Aufgaben bzw. Befehle ("Methodenaufruf"), in Targets auszuführen @@ -127,7 +127,7 @@ Works on my machine ... [Konsole/IDE: ant -f hello.xml]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/building/src/ant/hello.xml"} -## Properties: Name-Wert-Paare +# Properties: Name-Wert-Paare ```xml @@ -157,7 +157,7 @@ Works on my machine ... ::: -## Tasks zum Umgang mit Dateien und Ordnern +# Tasks zum Umgang mit Dateien und Ordnern ```xml @@ -184,7 +184,7 @@ Works on my machine ... ::: -## Nutzung von Filesets in Tasks +# Nutzung von Filesets in Tasks ```xml @@ -211,7 +211,7 @@ gruppieren. ::: -## Pfade und externe Bibliotheken +# Pfade und externe Bibliotheken * Als Element direkt im Task: @@ -288,9 +288,9 @@ Für JUnit5 gibt es einen neuen Task `JUnitLauncher` (vgl. ::::::::: notes -## Beispiele +# Beispiele -### Beispiel-Task: Kompilieren +## Beispiel-Task: Kompilieren ```xml @@ -304,7 +304,7 @@ Für JUnit5 gibt es einen neuen Task `JUnitLauncher` (vgl. ``` -### Beispiel-Task: Packen +## Beispiel-Task: Packen ```xml @@ -317,7 +317,7 @@ Für JUnit5 gibt es einen neuen Task `JUnitLauncher` (vgl. ``` -### Beispiel-Task: Testen +## Beispiel-Task: Testen * Tests einer Testklasse ausführen: @@ -381,7 +381,7 @@ Für JUnit5 gibt es einen neuen Task `JUnitLauncher` (vgl. => `junit.jar` und `ant-junit.jar` (JUnit4.x) im Pfad! -### Programme ausführen +## Programme ausführen ```xml @@ -396,7 +396,7 @@ Für JUnit5 gibt es einen neuen Task `JUnitLauncher` (vgl. ::::::::: -## Ausblick: Laden von Abhängigkeiten mit Apache Ivy +# Ausblick: Laden von Abhängigkeiten mit Apache Ivy ::: notes [Apache Ivy](https://ant.apache.org/ivy/): Dependency Manager für Ant @@ -468,7 +468,7 @@ Ivy-Cache unter ~/.ivy2/cache/ [Demo: ivydemo.xml]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/building/src/ant/ivydemo.xml"} -## Ausblick: Weitere Build-Systeme +# Ausblick: Weitere Build-Systeme * [Maven](https://maven.apache.org/) * War als Nachfolger von Ant gedacht @@ -489,7 +489,7 @@ Ivy-Cache unter ~/.ivy2/cache/ * Analog zu Ant: Aktionen und Ziele müssen explizit definiert werden -## Wrap-Up +# Wrap-Up Apache Ant: [ant.apache.org](https://ant.apache.org/) diff --git a/lecture/building/ci.md b/lecture/building/ci.md index dc06bace6..0385ab2bf 100644 --- a/lecture/building/ci.md +++ b/lecture/building/ci.md @@ -101,23 +101,23 @@ challenges: | ::::::::: notes -## Motivation: Zusammenarbeit in Teams +# Motivation: Zusammenarbeit in Teams -### Szenario +## Szenario * Projekt besteht aus diversen Teilprojekten * Verschiedene Entwicklungs-Teams arbeiten (getrennt) an verschiedenen Projekten * Tester entwickeln Testsuiten für die Teilprojekte * Tester entwickeln Testsuiten für das Gesamtprojekt -### Manuelle Ausführung der Testsuiten reicht nicht +## Manuelle Ausführung der Testsuiten reicht nicht * Belastet den Entwicklungsprozess * Keine (einheitliche) Veröffentlichung der Ergebnisse * Keine (einheitliche) Eskalation bei Fehlern * Keine regelmäßige Integration in Gesamtprojekt -### Continuous Integration +## Continuous Integration * Regelmäßige, automatische Ausführung: Build und Tests * Reporting @@ -125,12 +125,12 @@ challenges: | ::::::::: -## Continuous Integration (CI) +# Continuous Integration (CI) ![](images/ci.png){width="80%" web_width="60%"} ::::::::: notes -### Vorgehen +## Vorgehen * Entwickler und Tester committen ihre Änderungen regelmäßig (Git, SVN, ...) * CI-Server arbeitet Build-Skripte ab, getriggert durch Events: Push-Events, Zeit/Datum, ... @@ -141,14 +141,14 @@ challenges: | * Typische weitere Builds: "Nightly Build", Release-Build, ... * Ergebnisse jeweils auf der Weboberfläche einsehbar (und per E-Mail) -### Einige Vorteile +## Einige Vorteile * Tests werden regelmäßig durchgeführt (auch wenn sie lange dauern oder die Maschine stark belasten) * Es wird regelmäßig ein Gesamt-Build durchgeführt * Alle Teilnehmer sind über aktuellen Projekt(-zu-)stand informiert -### Beispiele für verbreitete CI-Umgebungen +## Beispiele für verbreitete CI-Umgebungen * [Jenkins](https://www.jenkins.io/) * [GitLab CI/CD](https://docs.gitlab.com/ee/ci/) @@ -161,13 +161,13 @@ challenges: | ::::::::: notes -## GitLab CI/CD +# GitLab CI/CD Siehe auch ["Get started with Gitlab CI/CD"](http://git03-ifm-min.ad.hsbi.de/help/ci/quick_start/index.md). (Für den Zugriff wird VPN benötigt!) -### Übersicht über Pipelines +## Übersicht über Pipelines ![](images/screenshot-gitlabci-pipelines.png){width="70%" web_width="60%"} @@ -182,14 +182,14 @@ Siehe auch ["Get started with Gitlab CI/CD"](http://git03-ifm-min.ad.hsbi.de/hel Wenn man mit der Maus auf den Status oder die Stages geht, erfährt man mehr bzw. kann auf eine Seite mit mehr Informationen kommen. -### Detailansicht einer Pipeline +## Detailansicht einer Pipeline ![](images/screenshot-gitlabci-triggeredpipeline.png){width="70%" web_width="60%"} Wenn man in eine Pipeline in der Übersicht klickt, werden die einzelnen Stages dieser Pipeline genauer dargestellt. -### Detailansicht eines Jobs +## Detailansicht eines Jobs ![](images/screenshot-gitlabci-job.png){width="70%" web_width="60%"} @@ -197,7 +197,7 @@ Wenn man in einen Job einer Stage klickt, bekommt man quasi die Konsolenausgabe dieses Jobs. Hier kann man ggf. Fehler beim Ausführen der einzelnen Skripte oder die Ergebnisse beispielsweise der JUnit-Läufe anschauen. -### GitLab CI/CD: Konfiguration mit YAML-Datei +## GitLab CI/CD: Konfiguration mit YAML-Datei Datei `.gitlab-ci.yml` im Projekt-Ordner: @@ -225,7 +225,7 @@ job3: stage: my.compile ``` -#### Stages +### Stages Unter `stages` werden die einzelnen Stages einer Pipeline definiert. Diese werden in der hier spezifizierten Reihenfolge durchgeführt, d.h. zuerst würde `my.compile` @@ -241,7 +241,7 @@ Wenn keine eigenen `stages` definiert werden, kann man auf die Default-Stages `build`, `test` und `deploy` zurückgreifen. **Achtung**: Sobald man eigene Stages definiert, stehen diese Default-Stages *nicht* mehr zur Verfügung! -#### Jobs +### Jobs `job1`, `job2` und `job3` definieren jeweils einen Job. @@ -267,7 +267,7 @@ Durch die Kombination von Jobs mit der Zuordnung zu Stages und Events lassen sich unterschiedliche Pipelines für verschiedene Zwecke definieren. -### Hinweise zur Konfiguration von GitLab CI/CD +## Hinweise zur Konfiguration von GitLab CI/CD Im Browser in den Repo-Einstellungen arbeiten: @@ -300,13 +300,13 @@ _Optional_: ::::::::: notes -## GitHub Actions +# GitHub Actions Siehe ["GitHub Actions: Automate your workflow from idea to production"](https://github.com/features/actions) und auch ["GitHub: CI/CD explained"](https://resources.github.com/ci-cd/). -### Übersicht über Workflows +## Übersicht über Workflows ![](images/screenshot-githubci-workflows.png){width="70%" web_width="60%"} @@ -318,7 +318,7 @@ Event filtern. In der Abbildung ist ein Workflow mit dem Namen "GitHub CI" zu sehen, der aktuell noch läuft. -### Detailansicht eines Workflows +## Detailansicht eines Workflows ![](images/screenshot-githubci-triggeredworkflow.png){width="70%" web_width="60%"} @@ -327,7 +327,7 @@ Jobs dieses Workflows genauer dargestellt. "job3" ist erfolgreich gelaufen, "job läuft gerade, und "job2" hängt von "job1" ab, d.h. kann erst nach dem erfolgreichen Lauf von "job2" starten. -### Detailansicht eines Jobs +## Detailansicht eines Jobs ![](images/screenshot-githubci-job.png){width="70%" web_width="60%"} @@ -335,7 +335,7 @@ Wenn man in einen Job anklickt, bekommt man quasi die Konsolenausgabe dieses Jobs. Hier kann man ggf. Fehler beim Ausführen der einzelnen Skripte oder die Ergebnisse beispielsweise der JUnit-Läufe anschauen. -### GitHub Actions: Konfiguration mit YAML-Datei +## GitHub Actions: Konfiguration mit YAML-Datei Workflows werden als YAML-Dateien im Ordner `.github/workflows/` angelegt. @@ -382,7 +382,7 @@ jobs: - run: echo "Job 3" ``` -#### Workflowname und Trigger-Events +### Workflowname und Trigger-Events Der Name des Workflows wird mit dem Eintrag `name` spezifiziert und sollte sich im Dateinamen widerspiegeln, also im Beispiel `.github/workflows/github_ci.yml`. @@ -391,7 +391,7 @@ Im Eintrag `on` können die Events definiert werden, die den Workflow triggern. Beispiel ist ein Push-Event auf dem `master`-Branch definiert sowie mit `workflow_dispatch:` das manuelle Triggern (auf einem beliebigen Branch) freigeschaltet. -#### Jobs +### Jobs Die Jobs werden unter dem Eintrag `jobs` definiert: `job1`, `job2` und `job3` definieren jeweils einen Job. @@ -431,7 +431,7 @@ Man kann auch einen Docker-Container benutzen. Dabei muss man beachten, dass die aus einer Registry (etwa von Docker-Hub oder aus der GitHub-Registry) "gezogen" wird, weil das Bauen des Docker-Containers aus einem Docker-File in der Action u.U. relativ lange dauert. -### Hinweise zur Konfiguration von GitHub Actions +## Hinweise zur Konfiguration von GitHub Actions Im Browser in den Repo-Einstellungen arbeiten: @@ -451,7 +451,7 @@ Im Browser in den Repo-Einstellungen arbeiten: ::::::::: -## Wrap-Up +# Wrap-Up Überblick über Continuous Integration: diff --git a/lecture/building/docker.md b/lecture/building/docker.md index 259efa10a..78e1dc241 100644 --- a/lecture/building/docker.md +++ b/lecture/building/docker.md @@ -69,7 +69,7 @@ attachments: -## Motivation CI/CD: WFM (_Works For Me_) +# Motivation CI/CD: WFM (_Works For Me_) ![](images/ci.png){width="80%" web_width="60%"} @@ -99,7 +99,7 @@ In diesen Fällen kann eine Virtualisierung helfen. ::: -## Virtualisierung: Container vs. VM +# Virtualisierung: Container vs. VM ![](images/virtualisierung.png){width="80%" web_width="60%"} @@ -143,7 +143,7 @@ normalerweise keine VMs/Container basierend auf ARM-Architektur ausgeführt werd ::: -## Getting started +# Getting started * DockerHub: fertige Images => [hub.docker.com/search](https://hub.docker.com/search?q=&type=image) @@ -153,7 +153,7 @@ normalerweise keine VMs/Container basierend auf ARM-Architektur ausgeführt werd * Image starten: `docker run ` ::: notes -### Begriffe +## Begriffe * **Docker-File**: Beschreibungsdatei, wie Docker ein Image erzeugen soll. * **Image**: Enthält die Dinge, die lt. dem Docker-File in das Image gepackt werden sollen. @@ -161,7 +161,7 @@ normalerweise keine VMs/Container basierend auf ARM-Architektur ausgeführt werd * **Container**: Ein laufendes Images (genauer: eine laufende Instanz eines Images). Kann dann auch zusätzliche Daten enthalten. -### Beispiele +## Beispiele ::: ::: slides @@ -229,7 +229,7 @@ dann mit `java Hello` die Klasse ausgeführt werden. [Demo: Container in der Konsole]{.ex href="https://youtu.be/LE_QcHqUg9Y"} -## Images selbst definieren +# Images selbst definieren ```docker FROM debian:stable-slim @@ -295,7 +295,7 @@ und erstellt ein neues, welches dann die aktualisierte Software enthält. [Beispiel: debian-latex.df]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/building/src/docker/debian-latex.df"} -## CI-Pipeline (GitLab) +# CI-Pipeline (GitLab) ```yaml default: @@ -324,7 +324,7 @@ Containers gesendet. Im Prinzip entspricht das dem Aufruf auf dem lokalen Rechne [Demo: GitLab CI/CD und Docker]{.ex href="https://youtu.be/3Tj3lhcoKro"} -## CI-Pipeline (GitHub) +# CI-Pipeline (GitHub) ```yaml name: demo @@ -360,7 +360,7 @@ Im Prinzip entspricht das dem Aufruf auf dem lokalen Rechner: `docker run openjd [Demo: GitHub Actions und Docker]{.ex href="https://youtu.be/jrxoax2fPRI"} -## VSCode und das Plugin "Remote - Containers" +# VSCode und das Plugin "Remote - Containers" ![](images/vscode-remote.png){width="80%"} @@ -407,7 +407,7 @@ von GitHub auf. ::::::::: notes -## Link-Sammlung +# Link-Sammlung * [Wikipedia: Docker](https://en.wikipedia.org/wiki/Docker_(software)) * [Wikipedia: Virtuelle Maschinen](https://en.wikipedia.org/wiki/Virtual_machine) @@ -422,7 +422,7 @@ von GitHub auf. ::::::::: -## Wrap-Up +# Wrap-Up * Schlanke Virtualisierung mit Containern (kein eigenes OS) * _Kein_ Sandbox-Effekt diff --git a/lecture/building/gradle.md b/lecture/building/gradle.md index 6454d2d00..fffaa3ed9 100644 --- a/lecture/building/gradle.md +++ b/lecture/building/gradle.md @@ -47,7 +47,7 @@ challenges: | --- -## Automatisieren von Arbeitsabläufen +# Automatisieren von Arbeitsabläufen ::: center Works on my machine ... @@ -106,7 +106,7 @@ Vorteil ist aber der Gradle-Wrapper (s.u.). ::: -## Gradle: Eine DSL in Groovy +# Gradle: Eine DSL in Groovy [DSL: _Domain Specific Language_]{.notes} @@ -151,7 +151,7 @@ Eintrag `application` den Einsprungpunkt in die Applikation konfigurieren. ::::::::: notes -## Gradle-DSL +# Gradle-DSL -## How-To Dungeon +# How-To Dungeon In diesem Semester werden Sie im Praktikum schrittweise Erweiterungen in verschiedenen "fertigen" Rogue-like Computerspielen programmieren und dabei (hoffentlich) die Methoden aus @@ -75,7 +75,7 @@ Wir werden uns in diesem How-To einen Überblick verschaffen und einen ersten Ei versuchen: Wir programmieren einen einfachen Helden. -## Projekt PM-Dungeon +# Projekt PM-Dungeon Das Projekt PM-Dungeon entstand in verschiedenen Forschungsprojekten und wurde (und wird) aktiv von Studierenden und wissenschaftlichen Mitarbeitern am Campus Minden entwickelt. @@ -94,7 +94,7 @@ von Klassen und Methoden, sinnvolles Javadoc, Dokumentation jenseits des Javadoc Commit-Messages und PR-Summaries. -## Installation des Frameworks +# Installation des Frameworks Sie finden das Projekt auf GitHub: [github.com/Dungeon-CampusMinden/Dungeon](https://github.com/Dungeon-CampusMinden/Dungeon). @@ -116,7 +116,7 @@ Sonderzeichen (Umlaute o.ä.) vorkommen! Dies kann zu seltsamen Fehler führen. darauf achten, dass Sie als JDK ein **Java SE 21 (LTS)** verwenden. -## Java: Java SE 21 (LTS) +# Java: Java SE 21 (LTS) Wir benutzen im Dungeon-Projekt die aktuelle LTS-Version des JDK, d.h. **Java SE 21 (LTS)**. Sie können sich das JDK bei [Oracle](https://www.oracle.com/java/technologies/downloads/) @@ -138,7 +138,7 @@ ungefähr diese Ausgabe erzeugen (ignorieren Sie die Minor-Version, wichtig ist Java HotSpot(TM) 64-Bit Server VM (build 21.0.3+7-LTS-152, mixed mode, sharing) -## Erster Test +# Erster Test Für einen ersten Test gehen Sie in der Konsole in den vorhin erzeugten neuen Ordner `pm-dungeon/` und führen Sie dort den Befehl @@ -157,7 +157,7 @@ Dies dauert je nach Internetanbindung etwas - beim nächsten Start geht es dann schneller, weil ja bereits alles da ist. -## Import in der IDE +# Import in der IDE Importieren Sie das Projekt als Gradle-basiertes Projekt, dann übernimmt die IDE die Konfiguration für Sie. @@ -170,7 +170,7 @@ Konfiguration für Sie. starten, und es erscheint wieder ein minimales Level. -## Überblick über die (Sub-) Projekte +# Überblick über die (Sub-) Projekte Sie finden im Package-Explorer eine Reihe von Unterprojekten (Gradle-Subprojekte). Für PR2 ist eigentlich nur das Subprojekt @@ -210,7 +210,7 @@ anschauen sollten. Zusätzlich gibt es für Game und Dungeon noch weitere Dokume `doc/`-Ordnern. -## Überblick über die Java-Strukturen +# Überblick über die Java-Strukturen ![](https://github.com/Dungeon-CampusMinden/Dungeon/blob/master/game/doc/img/gameloop.png?raw=true) @@ -248,7 +248,7 @@ Dungeon"](https://github.com/Dungeon-CampusMinden/Dungeon/blob/master/game/doc/q eine gute Anleitung, die auf die Strukturen tiefer eingeht. -## Mein Held +# Mein Held Um einen besseren Blick in das System zu bekommen, erstellen wir schrittweise einen eigenen einfachen Helden. @@ -281,7 +281,7 @@ tasks.register('run', JavaExec) { ``` -## Einschub: ECS oder Entities, Components und Systems +# Einschub: ECS oder Entities, Components und Systems Der Held ist ein Element im Spiel. Diese Struktur muss geeignet modelliert werden. @@ -293,7 +293,7 @@ Vorbildern" wie beispielsweise Neben verschiedenen Hilfsstrukturen gibt es dabei nur **Entitäten**, **Komponenten** und **Systeme**. Hier werden sämtliche Informationen und Verhalten modelliert. -### Entity +## Entity Die Idee dahinter ist: Alle Elemente im Spiel werden als *Entität* realisiert, d.h. der Held und die Monster und die Items, die man so finden kann, sind alles Entitäten. Sogar Feuerbälle @@ -308,7 +308,7 @@ registriert werden. Man kann die Entitäten über die API abrufen (`Game#allEnti Unsere Basisklasse für Entitäten ist aktuell `core.Entity`. -### Component +## Component Components bündeln bestimmte Werte einer Entität für bestimmte Zwecke, d.h. statt der Attribute in einer Klasse (Entität) nutzen wir hier eine weitere Kapselung. @@ -329,7 +329,7 @@ Components speichern vor allem Werte und haben nur in Ausnahmefällen eigenes Ve Das Basisinterface für Components ist derzeit `core.Component`. -### System +## System Mit Entitäten und passenden Components, über die wir die Eigenschaften ausdrücken, können wir bereits Spielelemente im Dungeon repräsentieren. @@ -353,9 +353,9 @@ Basisklasse ist derzeit `core.System` - falls Sie einmal eigene Systeme implemen Doku](https://github.com/Dungeon-CampusMinden/Dungeon/blob/master/game/doc/create_own_content.md)) -## Nun aber Helden! +# Nun aber Helden! -### Ein Held ist eine Entität +## Ein Held ist eine Entität Also legen wir nun endlich einen neuen Helden als Instanz von `core.Entity` an und registrieren diese Entität im Spiel: @@ -386,7 +386,7 @@ Prinzipiell haben Sie damit alles, um das Spiel starten zu können. In der Praxi aber keinen Helden: Der hat nämlich weder eine Position noch eine Textur, kann also gar nicht angezeigt werden. -### Wo bin ich grad? +## Wo bin ich grad? Der Held braucht eine Position. Dazu gibt es `core.components.PositionComponent`. Fügen wir diese einfach dem Helden hinzu: @@ -426,7 +426,7 @@ ist). Wenn Sie jetzt das Spiel starten, sehen Sie - immer noch nichts (außer den Wänden). Hmmm. -### Animateure +## Animateure Um den Held zeichnen zu können, brauchen wir eine Animation - also eine `DrawComponent`. @@ -482,7 +482,7 @@ gleich noch eine `PlayerComponent`. Jetzt wackelt der Held auf der Stelle herum ... -### Bewege mich +## Bewege mich Für die Bewegung ist das `VelocitySystem` zuständig. Dieses fragt in allen Entitäten die `VelocityComponent` sowie die `PositionComponent` ab, berechnet die nächste neue Position und @@ -569,9 +569,9 @@ Nun sollten Sie Ihren Helden (nach oben) bewegen können. (Tipp: Probieren Sie " diejenigen Entitäten, die alle benötigten Components aufweisen. -## Walking mit System +# Walking mit System -### Neue Monster +## Neue Monster Wie kann ich ein Monster beim Laden des Levels erzeugen? @@ -633,7 +633,7 @@ und dann "ewig" laufen, insbesondere bei Reaktion auf Tastatureingaben. Deshalb Entitäten kurz bewegt und bremsen dann wieder ab. Das Aufrechterhalten der Bewegung erfolgt normalerweise über Systeme ... -### Systems für das selbstständige Laufen +## Systems für das selbstständige Laufen Wir brauchen ein System, welches die aktuelle Geschwindigkeit einer Entität in jedem Frame wieder auf den alten Wert setzt. Dazu leiten wir von `core.System` ab. (Achtung: Es gibt auch @@ -683,7 +683,7 @@ Nun läuft das neue Monster los (bis es gegen eine Wand läuft). Aber der Held bewegt sich nun ebenfalls dauerhaft :( -### Components für das selbstständige Laufen +## Components für das selbstständige Laufen Das Problem ist, dass unser neues `WalkerSystem` **alle** Entitäten automatisch bewegt. (Ein weiteres Problem ist, dass das `WalkerSystem` davon ausgeht, dass es immer eine @@ -766,7 +766,7 @@ Tatsächlich gibt es im Sub-Projekt "dungeon" (Package `contrib`) bereits eine V Components und passenden Systems, die solche typischen Aufgaben bereits realisieren. -## Kämpfe wie ein NPC +# Kämpfe wie ein NPC Wir haben beim Hero über das `PlayerComponent` eine Reaktion auf Tastatureingaben implementiert. Hier könnte man einer Taste auch den Start einer neuen Entität zuordnen, die @@ -847,7 +847,7 @@ All diese (und viele weitere) Components und Systems gibt es bereits im Package Sub-Projekt ["dungeon"](https://github.com/Dungeon-CampusMinden/Dungeon/tree/master/dungeon). -## Wrap-Up +# Wrap-Up ::: notes Damit endet der kurze Ausflug in den Dungeon. diff --git a/lecture/misc/intro-frameworks.md b/lecture/misc/intro-frameworks.md index e199eb3e6..09f6786f3 100644 --- a/lecture/misc/intro-frameworks.md +++ b/lecture/misc/intro-frameworks.md @@ -24,12 +24,12 @@ fhmedia: --- -## Checkliste für die Entwicklung eines simplen Videospiels +# Checkliste für die Entwicklung eines simplen Videospiels ![](images/checklisteMotivation.png){width="60%"} -## Checkliste für die Entwicklung eines simplen Videospiels mit Framework +# Checkliste für die Entwicklung eines simplen Videospiels mit Framework ![](images/checklisteMotivationFarbig.png){width="60%"} @@ -47,7 +47,7 @@ werden, die Anfragen annimmt, bearbeitet und die Antworten wieder zurückliefert ::: -## Was sind Frameworks? +# Was sind Frameworks? ::: notes Frameworks liefern die Rahmenstruktur und Architektur, um Programme für die @@ -62,7 +62,7 @@ zu implementieren, sind dabei aber selbst keine eigenen Programme (vgl. PM-Dunge ::: ::: notes -## Unterschied zu Libraries +# Unterschied zu Libraries * Libraries stellen Funktionen bereit, die frei in der eigenen Implementierung genutzt werden können. @@ -84,7 +84,7 @@ zu implementieren, sind dabei aber selbst keine eigenen Programme (vgl. PM-Dunge ![](images/frameworksVSlib.png){width="80%"} -## Verbreitete Frameworks +# Verbreitete Frameworks | Framework | Anwendungszweck | |-----------|--------------------------------------------------| @@ -95,9 +95,9 @@ zu implementieren, sind dabei aber selbst keine eigenen Programme (vgl. PM-Dunge | libGDX | Game Development :) | -## Mögliche Vor- und Nachteile von Frameworks +# Mögliche Vor- und Nachteile von Frameworks -### (+) Vorteile +## (+) Vorteile * Ermöglichen eine schnelle Implementierung umfangreicher Softwarekonstrukte * Verstecken komplexe Zusammenhänge vor den Entwicklern @@ -106,7 +106,7 @@ zu implementieren, sind dabei aber selbst keine eigenen Programme (vgl. PM-Dunge \bigskip -### (-) Nachteile +## (-) Nachteile * Oftmals sehr umfangreich und schwer zu erlernen * Fokus oft nicht mehr nur auf einem Anwendungsbereich (z.B. Spring) @@ -117,14 +117,14 @@ zu implementieren, sind dabei aber selbst keine eigenen Programme (vgl. PM-Dunge ::: notes -## Frameworks finden +# Frameworks finden -### Wann sollte man Frameworks verwenden? +## Wann sollte man Frameworks verwenden? Wenn man bereits etablierte Anwendungen (wie Webservices) mit eigener Funktionalität anbieten möchte. -### Wie/Wo findet man passende Frameworks? +## Wie/Wo findet man passende Frameworks? * Internetrecherche * Foren @@ -132,7 +132,7 @@ Funktionalität anbieten möchte. ::: -## Wie starte ich mit einem Framework? +# Wie starte ich mit einem Framework? ::: notes Beispielproblem: Es soll eine interne Webanwendung bereitgestellt werden, die @@ -161,7 +161,7 @@ ist ein einfaches und schlankes Framework zu bevorzugen. [Demo: Web-Anwendung für Zufallszahlen]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/tree/master/lecture/misc/src/javalin/"} -## Wrap-Up +# Wrap-Up * Frameworks stellen einen Rahmen und eine Architektur für wiederkehrende Softwarestrukturen bereit diff --git a/lecture/pattern/command.md b/lecture/pattern/command.md index 4e1380543..f3336c71f 100644 --- a/lecture/pattern/command.md +++ b/lecture/pattern/command.md @@ -57,7 +57,7 @@ challenges: | --- -## Motivation +# Motivation ::: notes Irgendwo im Dungeon wird es ein Objekt einer Klasse ähnlich wie `InputHandler` @@ -89,7 +89,7 @@ zugeordnet und erlauben keinerlei Konfiguration. [[Problem: Starre Zuordnung]{.ex}]{.slides} -## Auflösen der starren Zuordnung über Zwischenobjekte +# Auflösen der starren Zuordnung über Zwischenobjekte ```java public interface Command { void execute(); } @@ -132,7 +132,7 @@ Beispiel oben wurde dafür der `hero` genutzt. ::: -## Command: Objektorientierte Antwort auf Callback-Funktionen +# Command: Objektorientierte Antwort auf Callback-Funktionen ![](images/command.png){web_width="80%"} @@ -167,7 +167,7 @@ In unserem Beispiel lassen sich die einzelnen Teile so sortieren: ::: -## Undo +# Undo ::: notes Wir könnten das `Command`-Interface um ein paar Methoden erweitern: @@ -230,7 +230,7 @@ keine weitere Buchhaltung ... ::: -## Wrap-Up +# Wrap-Up **Command-Pattern**: Kapsele Befehle in ein Objekt diff --git a/lecture/pattern/factory-method.md b/lecture/pattern/factory-method.md index aabb7b529..ee3d92d2c 100644 --- a/lecture/pattern/factory-method.md +++ b/lecture/pattern/factory-method.md @@ -78,7 +78,7 @@ challenges: | --- -## Motivation: Ticket-App +# Motivation: Ticket-App * Nutzer geben Fahrtziel an (und nicht die Ticketart!) @@ -94,12 +94,12 @@ challenges: | => **Factory-Method-Pattern**: Objekte sollen nicht direkt durch den Nutzer erzeugt werden -## Factory-Method-Pattern +# Factory-Method-Pattern ![](images/factorymethod.png){width="80%"} -## Hands-On: Ticket-App +# Hands-On: Ticket-App Implementieren Sie eine Ticket-App, die verschiedene Tickets mit Hilfe des Factory-Method Entwurfsmusters generiert. @@ -107,7 +107,7 @@ Hilfe des Factory-Method Entwurfsmusters generiert. [UML; Konsole: factory.FactoryBeispiel]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/pattern/src/factory/FactoryBeispiel.java"} -## Wrap-Up +# Wrap-Up * Konkrete Objekte sollen nicht direkt über Konstruktor erzeugt werden * (Statische) Hilfsmethode, die aus Parameter das "richtige" Objekte erzeugt diff --git a/lecture/pattern/flyweight.md b/lecture/pattern/flyweight.md index 737526366..944af694f 100644 --- a/lecture/pattern/flyweight.md +++ b/lecture/pattern/flyweight.md @@ -42,10 +42,10 @@ challenges: | --- -## Motivation: Modellierung eines Levels +# Motivation: Modellierung eines Levels ::: notes -### Variante I: Einsatz eines Enums für die Felder +## Variante I: Einsatz eines Enums für die Felder ::: ```java @@ -84,11 +84,11 @@ müssen _alle_ `switch/case`-Blöcke entsprechend angepasst werden. ::: slides -## Motivation: Modellierung eines Levels (cnt.) +# Motivation: Modellierung eines Levels (cnt.) ::: ::: notes -### Variante II: Einsatz einer Klasse/Klassenhierarchie für die Felder +## Variante II: Einsatz einer Klasse/Klassenhierarchie für die Felder ::: ```java @@ -124,7 +124,7 @@ geladen und entsprechend mehrfach im Speicher gehalten (großer Speicherbedarf). ::: -## Flyweight: Nutze gemeinsame Eigenschaften gemeinsam +# Flyweight: Nutze gemeinsame Eigenschaften gemeinsam ::: notes Idee: Eigenschaften, die nicht an einem konkreten Objekt hängen, werden in gemeinsam genutzte @@ -133,7 +133,7 @@ Objekte ausgelagert (Shared Objects/Memory). Ziel: Erhöhung der Speichereffizienz (geringerer Bedarf an Hauptspeicher, geringere Bandbreite bei der Übertragung der Daten/Objekt an die GPU, ...). -### Lösungsvorschlag I +## Lösungsvorschlag I ::: ```java @@ -171,11 +171,11 @@ wie etwa, ob ein Feld bereits durch den Helden untersucht/betreten wurde o.ä. . ::: slides -## Flyweight: Nutze gemeinsame Eigenschaften gemeinsam (cnt.) +# Flyweight: Nutze gemeinsame Eigenschaften gemeinsam (cnt.) ::: ::: notes -### Lösungsvorschlag II +## Lösungsvorschlag II ::: ```java @@ -220,7 +220,7 @@ je einmal im Speicher repräsentiert. ::: -## Flyweight-Pattern: Begriffe +# Flyweight-Pattern: Begriffe * **Intrinsic** State: invariant, Kontext-unabhängig, gemeinsam nutzbar \newline => auslagern in gemeinsame Objekte @@ -231,7 +231,7 @@ je einmal im Speicher repräsentiert. => individuell modellieren -## Flyweight-Pattern: Klassische Modellierung +# Flyweight-Pattern: Klassische Modellierung ![](images/flyweight.png){width="60%"} @@ -254,7 +254,7 @@ Zusätzlich gibt es Klassen, die extrinsischen Zustand modellieren und deshalb n Nutzern geteilt werden können und deren Objekte bei jeder Anfrage neu erstellt werden. Aber auch diese werden von der Factory erzeugt/verwaltet. -### Kombination mit dem Composite-Pattern +## Kombination mit dem Composite-Pattern In der Praxis kann man das Pattern so direkt meist nicht einsetzen, sondern verbindet es mit dem Composite-Pattern: @@ -266,7 +266,7 @@ oder eine zusammengesetzte Komponente, die ihrerseits andere Komponenten speiche Beispiel war das die Klasse `Tile`, die ein Objekt vom Typ `TileModel` referenziert - allerdings fehlt im obigen Beispiel das gemeinsame Interface ...). -### Level-Beispiel mit Flyweight (vollständig) und Composite +## Level-Beispiel mit Flyweight (vollständig) und Composite Im obigen Beispiel wurde zum Flyweight-Pattern noch das Composite-Pattern hinzugenommen, aber es wurde aus Gründen der Übersichtlichkeit auf ein gemeinsames Interface und auf die Factory @@ -336,7 +336,7 @@ public class Level { ::: notes -## Verwandtschaft zum Type-Object-Pattern +# Verwandtschaft zum Type-Object-Pattern Das [Flyweight-Pattern](https://gameprogrammingpatterns.com/flyweight.html) ist sehr ähnlich zum [Type-Object-Pattern](type-object.md). In beiden Pattern teilen @@ -351,7 +351,7 @@ werden. Die Zielrichtung unterscheidet sich aber deutlich: ::: -## Wrap-Up +# Wrap-Up Flyweight-Pattern: Steigerung der (Speicher-) Effizienz durch gemeinsame Nutzung von Objekten diff --git a/lecture/pattern/observer.md b/lecture/pattern/observer.md index ec6c8c69d..a0d438cbf 100644 --- a/lecture/pattern/observer.md +++ b/lecture/pattern/observer.md @@ -90,7 +90,7 @@ challenges: | --- -## Verteilung der Prüfungsergebnisse +# Verteilung der Prüfungsergebnisse ![](images/lsf.png){width="80%"} @@ -117,7 +117,7 @@ for (Person p : persons) { ::: -## Elegantere Lösung: Observer-Entwurfsmuster +# Elegantere Lösung: Observer-Entwurfsmuster ![](images/observerexample.png){width="80%"} @@ -132,7 +132,7 @@ die traditionell `update()` genannt wird. [Demo: observer]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/tree/master/lecture/pattern/src/observer/"} -## Observer-Pattern verallgemeinert +# Observer-Pattern verallgemeinert ![](images/observer.png){width="80%"} @@ -165,7 +165,7 @@ sondern implementieren Ihre eigenen Interfaces, wenn Sie das Observer-Pattern ei ::: -## Wrap-Up +# Wrap-Up Observer-Pattern: Benachrichtige registrierte Objekte über Statusänderungen diff --git a/lecture/pattern/singleton.md b/lecture/pattern/singleton.md index 77b5d251f..129cb7c6f 100644 --- a/lecture/pattern/singleton.md +++ b/lecture/pattern/singleton.md @@ -29,7 +29,7 @@ fhmedia: --- -## Motivation +# Motivation ```java public enum Fach { IFM, ELM, ARC } @@ -55,7 +55,7 @@ Beispiel für das Singleton-Pattern ... ::: -## Umsetzung: "Eager" Singleton Pattern +# Umsetzung: "Eager" Singleton Pattern ::: notes Damit man von "außen" keine Instanzen einer Klasse anlegen kann, versteckt man den Konstruktor, @@ -84,7 +84,7 @@ public class SingletonEager { [Beispiel: singleton.SingletonEager]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/pattern/src/singleton/SingletonEager.java"} -## Umsetzung: "Lazy" Singleton Pattern +# Umsetzung: "Lazy" Singleton Pattern ::: notes Beim "Lazy Singleton Pattern" wird das Objekt erst erzeugt, wenn die Instanz tatsächlich benötigt @@ -113,7 +113,7 @@ public class SingletonLazy { [Beispiel: singleton.SingletonLazy]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/pattern/src/singleton/SingletonLazy.java"} -## Vorsicht! +# Vorsicht! ::: center Sie schaffen damit eine globale Variable! @@ -129,7 +129,7 @@ Nutzen Sie das Pattern **sparsam**. ::: -## Wrap-Up +# Wrap-Up Singleton-Pattern: Klasse, von der nur genau ein Objekt instantiiert werden kann diff --git a/lecture/pattern/strategy.md b/lecture/pattern/strategy.md index 9b31afc06..4731f0bcb 100644 --- a/lecture/pattern/strategy.md +++ b/lecture/pattern/strategy.md @@ -60,7 +60,7 @@ challenges: | --- -## Wie kann man das Verhalten einer Klasse dynamisch ändern? +# Wie kann man das Verhalten einer Klasse dynamisch ändern? ![](images/hunde.png){width="60%"} @@ -77,7 +77,7 @@ auch konkrete Bulldoggen geben mag, die nur leise fiepen ... ::: -## Lösung: Delegation der Aufgabe an geeignetes Objekt +# Lösung: Delegation der Aufgabe an geeignetes Objekt ![](images/hunde_strat.png){width="80%"} @@ -109,7 +109,7 @@ Entwurfsmuster: **Strategy Pattern** ::: notes -## Exkurs UML: Assoziation vs. Aggregation vs. Komposition +# Exkurs UML: Assoziation vs. Aggregation vs. Komposition Eine **Assoziation** beschreibt eine Beziehung zwischen zwei (oder mehr) UML-Elementen (etwa Klassen oder Interfaces). @@ -135,7 +135,7 @@ und [Klassendiagramm](https://de.wikipedia.org/wiki/Klassendiagramm). ::: notes -## Zweites Beispiel: Sortieren einer Liste von Studis +# Zweites Beispiel: Sortieren einer Liste von Studis Sortieren einer Liste von Studis: `Collections.sort` kann eine Liste nach einem Default-Kriterium sortieren oder aber über einen extra @@ -169,7 +169,7 @@ unsicher sind! ::: -## Hands-On: Strategie-Muster +# Hands-On: Strategie-Muster Implementieren Sie das Strategie-Muster für eine Übersetzungsfunktion: @@ -190,7 +190,7 @@ Implementieren Sie das Strategie-Muster für eine Übersetzungsfunktion: ::: notes -## Auflösung +# Auflösung ![](images/translator.png){width="80%"} ::: @@ -198,7 +198,7 @@ Implementieren Sie das Strategie-Muster für eine Übersetzungsfunktion: [Konsole strategy.TranslatorExample]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/pattern/src/strategy/TranslatorExample.java"} -## Wrap-Up +# Wrap-Up Strategy-Pattern: Verhaltensänderung durch Delegation an passendes Objekt diff --git a/lecture/pattern/template-method.md b/lecture/pattern/template-method.md index b52f5f9af..5bb09637e 100644 --- a/lecture/pattern/template-method.md +++ b/lecture/pattern/template-method.md @@ -57,7 +57,7 @@ challenges: | --- -## Motivation: Syntax-Highlighting im Tokenizer +# Motivation: Syntax-Highlighting im Tokenizer ::: notes In einem Compiler ist meist der erste Arbeitsschritt, den Eingabestrom in einzelne @@ -104,7 +104,7 @@ der Liste `allToken` auf den aktuellen Anfang des Eingabestroms passt. ::: -## Token-Klassen mit formatiertem Inhalt +# Token-Klassen mit formatiertem Inhalt ::: notes Um den eigenen Tokenizer besser testen zu können, wurde beschlossen, dass jedes Token @@ -151,7 +151,7 @@ von DRY aus ... ::: -## Don't call us, we'll call you +# Don't call us, we'll call you ```java public abstract class Token { @@ -203,12 +203,12 @@ Dies ist ein Beispiel für das **[Template-Method-Pattern](https://en.wikipedia. ::: -## Template-Method-Pattern +# Template-Method-Pattern ![](images/template-method.png){width="80%" web_width="50%"} ::: notes -### Aufbau Template-Method-Pattern +## Aufbau Template-Method-Pattern In der Basisklasse implementiert man eine Template-Methode (in der Skizze `templateMethod`), die sich auf anderen in der Basisklasse deklarierten (Hilfs-) Methoden "abstützt" (diese also @@ -221,7 +221,7 @@ Verhalten so neu formulieren (in der Skizze `method3`). Damit werden Teile des Verhaltens an die ableitenden Klassen ausgelagert. -### Verwandtschaft zum Strategy-Pattern +## Verwandtschaft zum Strategy-Pattern Das Template-Method-Pattern hat eine starke Verwandtschaft zum Strategy-Pattern. @@ -238,7 +238,7 @@ im Template-Method-Pattern gewissermaßen nur Teile des Verhaltens an die ableit ::: -## Wrap-Up +# Wrap-Up Template-Method-Pattern: Verhaltensänderung durch Vererbungsbeziehungen diff --git a/lecture/pattern/type-object.md b/lecture/pattern/type-object.md index bcc33bd30..20b0b798c 100644 --- a/lecture/pattern/type-object.md +++ b/lecture/pattern/type-object.md @@ -66,7 +66,7 @@ challenges: | --- -## Motivation: Monster und spezialisierte Monster +# Motivation: Monster und spezialisierte Monster ```java public abstract class Monster { @@ -115,7 +115,7 @@ Konstruktor aufrufen. ::: -## Vereinfachen der Vererbungshierarchie (mit Enums als Type-Object) +# Vereinfachen der Vererbungshierarchie (mit Enums als Type-Object) ```java public enum Species { RAT, GNOLL, ... } @@ -160,7 +160,7 @@ muss man bei Erweiterungen des Enums auch _alle_ `switch/case`-Blöcke anpassen. ::: -## Monster mit Strategie +# Monster mit Strategie ```java public final class Species { @@ -206,7 +206,7 @@ Code, vermutlich `main()` oder beispielsweise durch Einlesen einer Konfig-Datei) ::: -## Fabrikmethode für die Type-Objects +# Fabrikmethode für die Type-Objects ```java public final class Species { @@ -235,7 +235,7 @@ einbauen, über die dann die Monster erzeugt werden. ::: -## Vererbung unter den Type-Objects +# Vererbung unter den Type-Objects ```java public final class Species { @@ -273,7 +273,7 @@ aus dem Eltern-Type-Object übernommen (sofern dieses übergeben wird). ::: -## Erzeugen der Type-Objects dynamisch über eine Konfiguration +# Erzeugen der Type-Objects dynamisch über eine Konfiguration ```json { @@ -303,14 +303,14 @@ erzeugt. ::: notes -## Vor- und Nachteile des Type-Object-Pattern +# Vor- und Nachteile des Type-Object-Pattern -### Vorteil +## Vorteil Es gibt nur noch wenige Klassen auf Code-Ebene (im Beispiel: 2), und man kann über die Konfiguration beliebig viele Monster-Typen erzeugen. -### Nachteil +## Nachteil Es werden zunächst nur Daten "überschrieben", d.h. man kann nur für die einzelnen Typen spezifische Werte mitgeben/definieren. @@ -320,7 +320,7 @@ Bei Vererbung kann man in den Unterklassen nahezu beliebig das Verhalten durch e dem man beispielsweise eine Reihe von vordefinierten Verhaltensarten implementiert, die dann anhand von Werten ausgewählt und anhand anderer Werte weiter parametrisiert werden. -### Verwandtschaft zum Flyweight-Pattern +## Verwandtschaft zum Flyweight-Pattern Das [Type-Object-Pattern](https://gameprogrammingpatterns.com/type-object.html) ist keines der ["klassischen" Design-Pattern](https://en.wikipedia.org/wiki/Design_Patterns) der "Gang @@ -338,7 +338,7 @@ gemeinsame Hilfsobjekte eingebunden werden. Die Zielrichtung unterscheidet sich ::: -## Wrap-Up +# Wrap-Up Type-Object-Pattern: Implementierung eines eigenen Objekt-Modells diff --git a/lecture/pattern/visitor.md b/lecture/pattern/visitor.md index eebf70f17..2a3cf9310 100644 --- a/lecture/pattern/visitor.md +++ b/lecture/pattern/visitor.md @@ -140,7 +140,7 @@ challenges: | --- -## Motivation: Parsen von "5*4+3" +# Motivation: Parsen von "5*4+3" ::::::::: {.columns} :::::: {.column width="50%"} @@ -171,7 +171,7 @@ Beim Parsen von "5*4+3" würde dabei der folgende Parsetree entstehen: ::::::::: -## Strukturen für den Parsetree +# Strukturen für den Parsetree ![](images/parsetree_classes_uml.png){width="70%"} @@ -222,7 +222,7 @@ public class DemoExpr { ::: -## Ergänzung I: Ausrechnen des Ausdrucks +# Ergänzung I: Ausrechnen des Ausdrucks ::: notes Es wäre nun schön, wenn man mit dem Parsetree etwas anfangen könnte. Vielleicht @@ -283,7 +283,7 @@ public class DemoExpr { ::: -## Ergänzung II: Pretty-Print des Ausdrucks +# Ergänzung II: Pretty-Print des Ausdrucks ::: notes Nachdem das Ausrechnen so gut geklappt hat, will der Chef nun noch flink eine Funktion, @@ -305,7 +305,7 @@ immer _alle_ Expression-Klassen anpassen! **Das geht besser.** -## Visitor-Pattern (Besucher-Entwurfsmuster) +# Visitor-Pattern (Besucher-Entwurfsmuster) ![](images/visitor.png){web_width="80%"} @@ -417,7 +417,7 @@ public class DemoExpr { } ``` -### Implementierungsdetail +## Implementierungsdetail In den beiden Klasse `AddExpr` und `MulExpr` müssen auch die beiden Kindknoten besucht werden, d.h. hier muss der Baum weiter traversiert werden. @@ -434,12 +434,12 @@ Post-Order, ...) und diese elegant in den Visitor verlagern kann. [Beispiel Traversierung extern (im Visitor): visitor.visit.extrav.DemoExpr]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/pattern/src/visitor/visit/extrav/DemoExpr.java"} -### (Double-) Dispatch +## (Double-) Dispatch Zur Laufzeit wird in `accept()` der Typ des Visitors aufgelöst und dann in `visit()` der Typ der zu besuchenden Klasse. Dies nennt man auch "Double-Dispatch". -### Hinweis I +## Hinweis I Man könnte versucht sein, die `accept()`-Methode aus den Knotenklassen in die gemeinsame Basisklasse zu verlagern: Statt @@ -465,7 +465,7 @@ public abstract class Expr { Dies wäre tatsächlich schön, weil man so Code-Duplizierung vermeiden könnte. Aber es funktioniert in Java leider nicht. (Warum?) -### Hinweis II +## Hinweis II Während die `accept()`-Methode nicht in die Basisklasse der besuchten Typen (im Bild oben die Klasse `Elem` bzw. im Beispiel oben die Klasse `Expr`) verlagert werden kann, kann man @@ -474,14 +474,14 @@ implementieren. ::: -## Ausrechnen des Ausdrucks mit einem Visitor +# Ausrechnen des Ausdrucks mit einem Visitor ![](images/parsetree_visitor_uml.png) [Demo: visitor.visit.extrav.DemoExpr]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/pattern/src/visitor/visit/extrav/DemoExpr.java"} -## Wrap-Up +# Wrap-Up **Visitor-Pattern**: Auslagern der Traversierung in eigene Klassenstruktur diff --git a/lecture/quality/codingrules.md b/lecture/quality/codingrules.md index 44eb8d8bd..883e68e3f 100644 --- a/lecture/quality/codingrules.md +++ b/lecture/quality/codingrules.md @@ -73,7 +73,7 @@ attachments: --- -## Coding Conventions: Richtlinien für einheitliches Aussehen von Code +# Coding Conventions: Richtlinien für einheitliches Aussehen von Code => Ziel: Andere Programmierer sollen Code schnell lesen können @@ -94,7 +94,7 @@ Beispiele: [Sun Code Conventions](https://www.oracle.com/technetwork/java/codeco [AOSP Java Code Style for Contributors](https://source.android.com/docs/setup/contribute/code-style) -## Beispiel nach Google Java Style/AOSP formatiert +# Beispiel nach Google Java Style/AOSP formatiert ```java package wuppie.deeplearning.strategy; @@ -153,7 +153,7 @@ auf [Google Java Style](https://google.github.io/styleguide/javaguide.html) und ::: -## Formatieren Sie Ihren Code (mit der IDE) +# Formatieren Sie Ihren Code (mit der IDE) ::: notes Sie können den Code manuell formatieren, oder aber (sinnvollerweise) über Tools @@ -187,7 +187,7 @@ formatieren lassen. Hier einige Möglichkeiten: ::::::::: notes -### Einstellungen der IDE's +## Einstellungen der IDE's * Eclipse: * `Project > Properties > Java Code Style > Formatter`: Coding-Style einstellen/einrichten @@ -210,7 +210,7 @@ Analog sollte man bei der Verwendung von Checkstyle auch in der IDE im Formatter Checkstyle-Regeln (s.u.) passend einstellen, sonst bekommt man durch Checkstyle Warnungen angezeigt, die man durch ein automatisches Formatieren _nicht_ beheben kann. -### Google Java Style und google-java-format +## Google Java Style und google-java-format Wer direkt den [Google Java Style](https://google.github.io/styleguide/javaguide.html) nutzt, kann auch den dazu passenden Formatter von Google einsetzen: @@ -219,7 +219,7 @@ Diesen kann man entweder als Plugin für IntelliJ/Eclipse einsetzen oder als Sta (Kommandozeile oder Build-Skripte) aufrufen. Wenn man sich noch einen entsprechenden Git-Hook definiert, wird vor jedem Commit der Code entsprechend den Richtlinien formatiert :) -### Spotless und google-java-format in Gradle +## Spotless und google-java-format in Gradle _Hinweis_: Bei Spotless in Gradle müssen je nach den Versionen von Spotless/google-java-format bzw. des JDK noch Optionen in der Datei `gradle.properties` eingestellt werden (siehe @@ -241,14 +241,14 @@ docker run --rm -it -v "$PWD":/data -w /data --entrypoint "bash" gradle [Demo: Konfiguration Formatter (IDE), Spotless/Gradle]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/quality/src/formatter/"} -## Metriken: Kennzahlen für verschiedene Aspekte zum Code +# Metriken: Kennzahlen für verschiedene Aspekte zum Code ::::::::: notes Metriken messen verschiedene Aspekte zum Code und liefern eine Zahl zurück. Mit Metriken kann man beispielsweise die Einhaltung der Coding Rules (Formate, ...) prüfen, aber auch die Einhaltung verschiedener Regeln des objektorientierten Programmierens. -### Beispiele für wichtige Metriken (jeweils Max-Werte für PM) +## Beispiele für wichtige Metriken (jeweils Max-Werte für PM) Die folgenden Metriken und deren Maximal-Werte sind gute Erfahrungswerte aus der Praxis und helfen, den Code Smell "Langer Code" (vgl. ["Code Smells"](smells.md)) zu @@ -280,7 +280,7 @@ Dennoch sind das keine absoluten Werte an sich. Ein Übertreten der Grenzen ist **Hinweis** darauf, dass **höchstwahrscheinlich** etwas nicht stimmt, muss aber im konkreten Fall hinterfragt und diskutiert und begründet werden! -### Metriken im Beispiel von oben +## Metriken im Beispiel von oben ```java private static String lastName; @@ -311,7 +311,7 @@ d.h. `String` würde im obigen Beispiel _nicht_ bei DAC mitgezählt/angezeigt. => Verweis auf LV Softwareengineering -## Tool-Support: Checkstyle +# Tool-Support: Checkstyle ::::::::: notes Metriken und die Einhaltung von Coding-Conventions werden sinnvollerweise nicht manuell, @@ -359,7 +359,7 @@ docker run --rm -it -v "$PWD":/data -w /data --entrypoint "bash" gradle [Demo: IntelliJ, Checkstyle/Gradle]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/tree/master/lecture/quality/src/checkstyle/"} -## Checkstyle: Konfiguration +# Checkstyle: Konfiguration ::::::::: notes Die auszuführenden Checks lassen sich über eine [XML-Datei](https://checkstyle.org/config.html) @@ -413,7 +413,7 @@ Alternativen/Ergänzungen: beispielsweise [MetricsReloaded](https://github.com/B [Demo: Konfiguration mit Eclipse-CS, Hinweis auf Formatter]{.ex href="https://youtu.be/0ny6e6CNTF8"} -## SpotBugs: Finde Anti-Pattern und potentielle Bugs (Linter) +# SpotBugs: Finde Anti-Pattern und potentielle Bugs (Linter) * [**SpotBugs**](https://github.com/spotbugs/spotbugs) sucht nach über 400 potentiellen Bugs im Code * Anti-Pattern (schlechte Praxis, "dodgy" Code) @@ -448,7 +448,7 @@ docker run --rm -it -v "$PWD":/data -w /data --entrypoint "bash" gradle [Demo: SpotBugs/Gradle]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/tree/master/lecture/quality/src/spotbugs/"} -## Konfiguration für das PM-Praktikum (Format, Metriken, Checkstyle, SpotBugs) +# Konfiguration für das PM-Praktikum (Format, Metriken, Checkstyle, SpotBugs) ::: notes Im PM-Praktikum beachten wir die obigen Coding Conventions und Metriken mit den dort definierten @@ -456,7 +456,7 @@ Grenzwerten. Diese sind bereits in der bereit gestellten Minimal-Konfiguration f (s.u.) konfiguriert. ::: -### Formatierung +## Formatierung * Google Java Style/AOSP: **Spotless** @@ -473,7 +473,7 @@ Formatter Ihrer IDE entsprechend ein. \bigskip -### Checkstyle +## Checkstyle * Minimal-Konfiguration für **Checkstyle** (Coding Conventions, Metriken) @@ -557,7 +557,7 @@ Google Java Style hinaus. \bigskip -### Linter: SpotBugs +## Linter: SpotBugs * Vermeiden von Anti-Pattern mit **SpotBugs** @@ -567,7 +567,7 @@ Fehler beinhalten, die SpotBugs melden würde. ::: -## Wrap-Up +# Wrap-Up * Code entsteht nicht zum Selbstzweck => Regeln nötig! * Coding Conventions diff --git a/lecture/quality/javadoc.md b/lecture/quality/javadoc.md index cf1949db0..cdc52ffeb 100644 --- a/lecture/quality/javadoc.md +++ b/lecture/quality/javadoc.md @@ -53,7 +53,7 @@ challenges: | --- -## Dokumentation mit Javadoc +# Dokumentation mit Javadoc ```java /** @@ -83,7 +83,7 @@ Aufruf gern für Sie tätigt). ::: -## Standard-Aufbau +# Standard-Aufbau ```java /** @@ -134,7 +134,7 @@ public int setDate(int date) { ::: -## Veraltete Elemente +# Veraltete Elemente ```java /** @@ -156,7 +156,7 @@ beibehalten und danach das veraltete Element aus der API entfernt. ::: -## Autoren, Versionen, ... +# Autoren, Versionen, ... ```java /** @@ -175,7 +175,7 @@ Diese Annotationen finden Sie vor allem in Kommentaren zu Packages oder Klassen. ::: -## Was muss kommentiert werden? +# Was muss kommentiert werden? * Alle `public` Klassen * Alle `public` und `protected` Elemente der Klassen @@ -190,7 +190,7 @@ Diese Annotationen finden Sie vor allem in Kommentaren zu Packages oder Klassen. Alle anderen Elemente bei Bedarf mit _normalen_ Kommentaren versehen. ::: notes -### Beispiel aus dem JDK: ArrayList +## Beispiel aus dem JDK: ArrayList Schauen Sie sich gern mal Klassen aus der Java-API an, beispielsweise eine `java.util.ArrayList`: * Generierte Dokumentation: @@ -198,14 +198,14 @@ Schauen Sie sich gern mal Klassen aus der Java-API an, beispielsweise eine `java bzw. [direkt](https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html) * Quellcode: [ArrayList.java](https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/ArrayList.java) -### Best Practices: Was beschreibe ich eigentlich? +## Best Practices: Was beschreibe ich eigentlich? Unter [Documentation Best Practices](https://github.com/google/styleguide/blob/gh-pages/docguide/best_practices.md#documentation-is-the-story-of-your-code) finden Sie eine sehr gute Beschreibung, was das Ziel der Dokumentation sein sollte. Versuchen Sie, dieses zu erreichen! ::: -## Wrap-Up +# Wrap-Up * Javadoc-Kommentare sind normale Block-Kommentare beginnend mit `/**` * Generierung der HTML-Dokumentation mit `javadoc *.java` diff --git a/lecture/quality/junit-basics.md b/lecture/quality/junit-basics.md index 22d88e486..e5c69a3a6 100644 --- a/lecture/quality/junit-basics.md +++ b/lecture/quality/junit-basics.md @@ -129,7 +129,7 @@ challenges: | --- -## JUnit: Ergebnis prüfen +# JUnit: Ergebnis prüfen Klasse **`org.junit.Assert`** enthält diverse **statische** Methoden zum Prüfen: @@ -150,7 +150,7 @@ void fail(); ``` -## To "assert" or to "assume"? +# To "assert" or to "assume"? * Mit `assert*` werden Testergebnisse geprüft * Test wird ausgeführt @@ -165,7 +165,7 @@ void fail(); [Beispiel: junit4.TestAssume]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/quality/src/junit4/TestAssume.java"} -## Setup und Teardown: Testübergreifende Konfiguration +# Setup und Teardown: Testübergreifende Konfiguration ```java private Studi x; @@ -208,7 +208,7 @@ In JUnit 5 wurden die Namen dieser Annotationen leicht geändert: ::: notes -## Beispiel für den Einsatz von `@Before` +# Beispiel für den Einsatz von `@Before` Annahme: **alle/viele** Testmethoden brauchen **neues** Objekt `x` vom Typ `Studi` @@ -236,7 +236,7 @@ public void testGetName() { ::: notes -## Ignorieren von Tests +# Ignorieren von Tests * Hinzufügen der Annotation `@Ignore` * Alternativ mit Kommentar: `@Ignore("Erst im nächsten Release")` @@ -269,7 +269,7 @@ mit dem Grund für das Ignorieren des Tests hinterlegen. ::: -## Vermeidung von Endlosschleifen: Timeout +# Vermeidung von Endlosschleifen: Timeout ::: notes * Testfälle werden nacheinander ausgeführt @@ -316,7 +316,7 @@ void testTestDauerlaeufer() { ::: -## Test von Exceptions: Expected +# Test von Exceptions: Expected ::: notes Traditionelles Testen von Exceptions mit `try` und `catch`: @@ -370,7 +370,7 @@ public void testExceptAnnot() { ::: -## Parametrisierte Tests +# Parametrisierte Tests ::: notes Manchmal möchte man den selben Testfall mehrfach mit anderen Werten (Parametern) @@ -410,7 +410,7 @@ sind (Code-Duplizierung). ::: notes -### Parametrisierte Tests mit JUnit 4 +## Parametrisierte Tests mit JUnit 4 JUnit 4 bietet für dieses Problem sogenannte "parametrisierte Tests" an. Dafür muss eine Testklasse in JUnit 4 folgende Bedingungen erfüllen: @@ -438,10 +438,11 @@ Letztlich wird damit das Kreuzprodukt aus Testmethoden und Testdaten durchgefüh ::: ::: slides -## Parametrisierte Tests: Konstruktor (JUnit 4) +# Parametrisierte Tests: Konstruktor (JUnit 4) ::: + ::: notes -#### (A) Parametrisierte Tests: Konstruktor (JUnit 4) +### (A) Parametrisierte Tests: Konstruktor (JUnit 4) ::: ```java @@ -466,10 +467,11 @@ public class SumTestConstructor { ``` ::: slides -## Parametrisierte Tests: Parameter (JUnit 4) +# Parametrisierte Tests: Parameter (JUnit 4) ::: + ::: notes -#### (B) Parametrisierte Tests: Parameter (JUnit 4) +### (B) Parametrisierte Tests: Parameter (JUnit 4) ::: ```java @@ -496,7 +498,7 @@ public class SumTestParameters { ::: notes -### Parametrisierte Tests mit JUnit 5 +## Parametrisierte Tests mit JUnit 5 In JUnit 5 werden [parametrisierte Tests] mit der Annotation [`@ParameterizedTest`] gekennzeichnet (statt mit `@Test`). @@ -547,7 +549,7 @@ public class SumTest { ::: -## Testsuiten: Tests gemeinsam ausführen (JUnit 4) +# Testsuiten: Tests gemeinsam ausführen (JUnit 4) ::: notes Eclipse: `New > Other > Java > JUnit > JUnit Test Suite` @@ -571,7 +573,7 @@ public class MyTestSuite { ``` ::: notes -## Testsuiten mit JUnit 5 +# Testsuiten mit JUnit 5 In JUnit 5 gibt es zwei Möglichkeiten, Testsuiten zu erstellen: @@ -600,7 +602,7 @@ auf der "JUnit 5"-Plattform ausgeführt, sondern mit der JUnit 4-Infrastuktur! ::: notes -## Best Practices +# Best Practices 1. Ein Testfall behandelt exakt eine Idee/ein Szenario. Das bedeutet auch, dass man in der Regel nur ein bis wenige `assert*` pro Testmethode benutzt. @@ -664,7 +666,7 @@ Diese Erfahrungen werden ausführlich in [@SWEGoogle, pp. 231-256] diskutiert. ::: -## Wrap-Up +# Wrap-Up JUnit als Framework für (Unit-) Tests; hier JUnit 4 (mit Ausblick auf JUnit 5) diff --git a/lecture/quality/mockito.md b/lecture/quality/mockito.md index ac4247c38..1092fa156 100644 --- a/lecture/quality/mockito.md +++ b/lecture/quality/mockito.md @@ -170,10 +170,10 @@ challenges: | --- -## Motivation: Entwicklung einer Studi-/Prüfungsverwaltung +# Motivation: Entwicklung einer Studi-/Prüfungsverwaltung ::: notes -### Szenario +## Szenario Zwei Teams entwickeln eine neue Studi-/Prüfungsverwaltung für die Hochschule. Ein Team modelliert dabei die Studierenden, ein anderes Team modelliert die Prüfungsverwaltung LSF. @@ -220,7 +220,7 @@ Wie kann Team A seinen Code testen? ::: ::::::::: notes -### Motivation Mocking und Mockito +## Motivation Mocking und Mockito [Mockito](https://github.com/mockito/mockito) ist ein Mocking-Framework für JUnit. Es simuliert das Verhalten eines realen Objektes oder einer realen Methode. @@ -250,7 +250,7 @@ externen Abhängigkeiten zu lösen, indem es sogenannte Mocks, Stubs oder Spies anbietet, mit denen sich das Verhalten der realen Objekte simulieren/überwachen und testen lässt. -### Aber was genau ist denn jetzt eigentlich Mocking? +## Aber was genau ist denn jetzt eigentlich Mocking? Ein Mock-Objekt ("etwas vortäuschen") ist im Software-Test ein Objekt, das als Platzhalter (Attrappe) für das echte Objekt verwendet wird. @@ -277,7 +277,7 @@ Dabei ist es von Vorteil die drei Grundbegriffe "Mock", "Stub" oder "Spy", auf d in der Vorlesung noch häufiger treffen werden, voneinander abgrenzen und unterscheiden zu können. -### Dabei bezeichnet ein +## Dabei bezeichnet ein * **Stub**: Ein Stub ist ein Objekt, dessen Methoden nur mit einer minimalen Logik für den Test implementiert wurden. Häufig werden dabei einfach feste (konstante) @@ -288,7 +288,7 @@ unterscheiden zu können. * **Spy**: Ein Spy ist ein Objekt, welches Aufrufe und übergebene Werte protokolliert und abfragbar macht. Es ist also eine Art Wrapper um einen Stub oder einen Mock. -### Mockito Setup +## Mockito Setup * Gradle: `build.gradle` @@ -317,7 +317,7 @@ unterscheiden zu können. ::::::::: -## Manuell Stubs implementieren +# Manuell Stubs implementieren ::: notes Team A könnte manuell das LSF rudimentär implementieren (nur für die Tests, einfach mit @@ -356,7 +356,7 @@ Wenn man im Test andere Antworten braucht, müsste man einen weiteren Stub anleg [Demo hsbi.StudiStubTest]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/quality/src/mockito/src/test/java/hsbi/StudiStubTest.java"} -## Mockito: Mocking von ganzen Klassen +# Mockito: Mocking von ganzen Klassen ::: notes **Lösung**: Mocking der Klasse `LSF` mit Mockito für den Test von `Studi`: `mock()`. @@ -407,7 +407,7 @@ Mit Hilfe der Argument-Matcher `anyString()` wird jedes String-Argument akzeptie [Demo hsbi.StudiMockTest]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/quality/src/mockito/src/test/java/hsbi/StudiMockTest.java"} -## Mockito: Spy = Wrapper um ein Objekt +# Mockito: Spy = Wrapper um ein Objekt ::: notes Team B hat das `LSF` nun implementiert und Team A kann es endlich für die Tests benutzen. Aber @@ -460,7 +460,7 @@ Auch hier können Argument-Matcher wie `anyString()` eingesetzt werden. [Demo hsbi.StudiSpyTest]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/quality/src/mockito/src/test/java/hsbi/StudiSpyTest.java"} -## Wurde eine Methode aufgerufen? +# Wurde eine Methode aufgerufen? ```java public class VerifyTest { @@ -521,7 +521,7 @@ Reihenfolge bringen und so überprüfen. [Demo hsbi.VerifyTest]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/quality/src/mockito/src/test/java/hsbi/VerifyTest.java"} -## Fangen von Argumenten +# Fangen von Argumenten ```java public class MatcherTest { @@ -569,7 +569,7 @@ von [Mockito](https://javadoc.io/doc/org.mockito/mockito-core/) an. [Demo hsbi.MatcherTest]{.ex href="https://github.com/Programmiermethoden-CampusMinden/Prog2-Lecture/blob/master/lecture/quality/src/mockito/src/test/java/hsbi/MatcherTest.java"} -## Ausblick: PowerMock +# Ausblick: PowerMock Mockito sehr mächtig, aber unterstützt (u.a.) keine @@ -586,7 +586,7 @@ Mockito sehr mächtig, aber unterstützt (u.a.) keine ::::::::: notes -## Ausführlicheres Beispiel: WuppiWarenlager +# Ausführlicheres Beispiel: WuppiWarenlager **Credits**: Der Dank für die Erstellung des nachfolgenden Beispiels und Textes geht an [\@jedi101](https://github.com/jedi101). @@ -612,7 +612,7 @@ händisch in den Stub des Warenlagers einpflegen. Das will eigentlich niemand... -### Einsatz von Mockito +## Einsatz von Mockito Aber es gibt da einen Ausweg. Wenn es komplexer wird, verwenden wir Mocks. @@ -651,7 +651,7 @@ bestellteWuppis = wuppiStore.bestelleAlleWuppis(lager); assertEquals(2,bestellteWuppis.size()); ``` -### Mockito Spies +## Mockito Spies Manchmal möchten wir allerdings nicht immer gleich ein ganzes Objekt mocken, aber dennoch Einfluss auf die aufgerufenen Methoden eines Objekts haben, um @@ -692,7 +692,7 @@ Die normalen Testmöglichkeiten von JUnit runden unseren Test zudem ab. assertEquals(1,wuppiWarenlager.lager.size()); ``` -## Mockito und Annotationen +# Mockito und Annotationen In Mockito können Sie wie oben gezeigt mit `mock()` und `spy()` neue Mocks bzw. Spies erzeugen und mit `verify()` die Interaktion überprüfen @@ -759,7 +759,7 @@ ein kleiner Überblick über die wichtigsten in Mockito verwendeten Annotation: `@BeforeEach`). -### Prüfen der Interaktion mit _verify()_ +## Prüfen der Interaktion mit _verify()_ Mit Hilfe der umfangreichen `verify()`-Methoden, die uns Mockito mitliefert, können wir unseren Code unter anderem auf unerwünschte Seiteneffekte testen. So ist es mit @@ -814,7 +814,7 @@ public void testVerify_InteraktionenMitHilfeDesArgumentCaptor() { ::::::::: -## Wrap-Up +# Wrap-Up * Gründliches Testen ist ebenso viel Aufwand wie Coden! diff --git a/lecture/quality/refactoring.md b/lecture/quality/refactoring.md index 8b1f75fe9..504a38033 100644 --- a/lecture/quality/refactoring.md +++ b/lecture/quality/refactoring.md @@ -58,7 +58,7 @@ challenges: | --- -## Was ist Refactoring? +# Was ist Refactoring? > Refactoring ist, wenn einem auffällt, daß der Funktionsname `foobar` > ziemlich bescheuert ist, und man die Funktion in `sinus` umbenennt. @@ -87,7 +87,7 @@ challenges: | ::: -## Anzeichen, dass Refactoring jetzt eine gute Idee wäre +# Anzeichen, dass Refactoring jetzt eine gute Idee wäre * Code "stinkt" (zeigt/enthält _Code Smells_) @@ -145,7 +145,7 @@ sinnvoll ist. ::: -## Bevor Sie loslegen ... +# Bevor Sie loslegen ... 1. **Unit Tests** schreiben * Normale und ungültige Eingaben @@ -162,10 +162,10 @@ sinnvoll ist. 3. Haben Sie die fragliche Codestelle auch wirklich verstanden?! -## Vorgehen beim Refactoring +# Vorgehen beim Refactoring ::: notes -### Überblick über die Methoden des Refactorings +## Überblick über die Methoden des Refactorings Die Refactoring-Methoden sind nicht einheitlich definiert, es existiert ein großer und uneinheitlicher "Katalog" an möglichen Schritten. Teilweise benennt jede IDE @@ -179,7 +179,7 @@ Zu den am häufigsten genutzten Methoden zählen * Move Method * Pull Up, Push Down (Field, Method) -### Best Practice +## Best Practice Eine Best Practice (oder nennen Sie es einfach eine wichtige Erfahrung) ist, beim Refactoring langsam und gründlich vorzugehen. Sie ändern die Struktur @@ -200,22 +200,22 @@ grün sein (oder Sie haben einen Fehler gemacht). * Versionskontrolle nutzen: **Jeden** Schritt **einzeln** committen -## Refactoring-Methode: Rename Method/Class/Field +# Refactoring-Methode: Rename Method/Class/Field ::: notes -### Motivation +## Motivation Name einer Methode/Klasse/Attributs erklärt nicht ihren Zweck. -### Durchführung +## Durchführung Name selektieren, "`Refactor > Rename`" -### Anschließend ggf. prüfen +## Anschließend ggf. prüfen Aufrufer? Superklassen? -### Beispiel +## Beispiel ::: **Vorher** @@ -232,22 +232,22 @@ public String getTelefonNummer() {} -## Refactoring-Methode: Encapsulate Field +# Refactoring-Methode: Encapsulate Field ::: notes -### Motivation +## Motivation Sichtbarkeit von Attributen reduzieren. -### Durchführung +## Durchführung Attribut selektieren, "`Refactor > Encapsulate Field`" -### Anschließend ggf. prüfen +## Anschließend ggf. prüfen Superklassen? Referenzen? (Neue) JUnit-Tests? -### Beispiel +## Beispiel ::: **Vorher** @@ -274,10 +274,10 @@ public void printDetails() { ``` -## Refactoring-Methode: Extract Method/Class +# Refactoring-Methode: Extract Method/Class ::: notes -### Motivation +## Motivation * Codefragment stellt eigenständige Methode dar * "Überschriften-Code" @@ -285,11 +285,11 @@ public void printDetails() { * Code ist zu "groß" * Klasse oder Methode erfüllt unterschiedliche Aufgaben -### Durchführung +## Durchführung Codefragment selektieren, "`Refactor > Extract Method`" bzw. "`Refactor > Extract Class`" -### Anschließend ggf. prüfen +## Anschließend ggf. prüfen * Aufruf der neuen Methode? Nutzung der neuen Klasse? * Neue JUnit-Tests nötig? Veränderung bestehender Tests nötig? @@ -298,7 +298,7 @@ Codefragment selektieren, "`Refactor > Extract Method`" bzw. "`Refactor > Extrac * Veränderung lokaler Variablen: Rückgabewert in neuer Methode und Zuweisung bei Aufruf; evtl. neue Typen nötig! -### Beispiel +## Beispiel ::: **Vorher** @@ -326,20 +326,20 @@ private void printDetails() { ``` -## Refactoring-Methode: Move Method +# Refactoring-Methode: Move Method ::: notes -### Motivation +## Motivation Methode nutzt (oder wird genutzt von) mehr Eigenschaften einer fremden Klasse als der eigenen Klasse. -### Durchführung +## Durchführung Methode selektieren, "`Refactor > Move`" (ggf. "Keep original method as delegate to moved method" aktivieren) -### Anschließend ggf. prüfen +## Anschließend ggf. prüfen * Aufruf der neuen Methode (Delegation)? * Neue JUnit-Tests nötig? Veränderung bestehender Tests nötig? @@ -347,7 +347,7 @@ Methode selektieren, "`Refactor > Move`" * Veränderung lokaler Variablen: Rückgabewert in neuer Methode und Zuweisung bei Aufruf; evtl. neue Typen nötig! -### Beispiel +## Beispiel ::: **Vorher** @@ -371,7 +371,7 @@ public class Studi extends Person { ``` ::: slides -## Refactoring-Methode: Move Method (cnt.) +# Refactoring-Methode: Move Method (cnt.) ::: **Nachher** @@ -397,24 +397,24 @@ public class Studi extends Person { ``` -## Refactoring-Methode: Pull Up, Push Down (Field, Method) +# Refactoring-Methode: Pull Up, Push Down (Field, Method) ::: notes -### Motivation +## Motivation * Attribut/Methode nur für die Oberklasse relevant: **Pull Up** * Subklassen haben identische Attribute/Methoden: **Pull Up** * Attribut/Methode nur für eine Subklasse relevant: **Push Down** -### Durchführung +## Durchführung Name selektieren, "`Refactor > Pull Up`" oder "`Refactor > Push Down`" -### Anschließend ggf. prüfen +## Anschließend ggf. prüfen Referenzen/Aufrufer? JUnit-Tests? -### Beispiel +## Beispiel ::: **Vorher** @@ -439,7 +439,7 @@ public class Studi extends Person { ``` -## Wrap-Up +# Wrap-Up Behebung von **Bad Smells** durch **Refactoring** diff --git a/lecture/quality/smells.md b/lecture/quality/smells.md index 6045039b3..8fd3ad269 100644 --- a/lecture/quality/smells.md +++ b/lecture/quality/smells.md @@ -36,7 +36,7 @@ attachments: --- -## Code Smells: Ist das Code oder kann das weg? +# Code Smells: Ist das Code oder kann das weg? ```java class checker { @@ -88,7 +88,7 @@ Schauen Sie mal in die unten angegebene Literatur :-) ::: -## Was ist guter ("sauberer") Code ("Clean Code")? +# Was ist guter ("sauberer") Code ("Clean Code")? ::: notes Im Grunde bezeichnet "sauberer Code" ("Clean Code") die Abwesenheit von Smells. D.h. man @@ -112,7 +112,7 @@ zu diesem Thema zu Wort kommen - eine sehr lesenswerte Lektüre! => Jemand kümmert sich um den Code; solides Handwerk -## Warum ist guter ("sauberer") Code so wichtig? +# Warum ist guter ("sauberer") Code so wichtig? > Any fool can write code that a computer can understand. > Good programmers write code that humans can understand. @@ -131,7 +131,7 @@ Praxis später nicht gut gepflegt: Andere Entwickler haben (die berechtigte) Ang kaputt zu machen und arbeiten "um den Code herum". Nur leider wird das Konstrukt dann nur noch schwerer verständlich ... -### Code Smells +## Code Smells Verstöße gegen die Prinzipien von _Clean Code_ nennt man auch _Code Smells_: Der Code "stinkt" gewissermaßen. Dies bedeutet nicht unbedingt, dass der Code nicht @@ -151,7 +151,7 @@ was im Laufe der Zeit die Chance für tatsächliche Probleme deutlich erhöht. ::: ::::::::: notes -### "Broken Windows" Phänomen +## "Broken Windows" Phänomen Wenn ein Gebäude leer steht, wird es eine gewisse Zeit lang nur relativ langsam verfallen: Die Fenster werden nicht mehr geputzt, es sammelt sich Graffiti, Gras @@ -173,7 +173,7 @@ schlecht ist ... Das wird mit der Zeit nicht besser ... ["Broken Windows" Phänomen]{.ex href="https://en.wikipedia.org/wiki/Broken_windows_theory"} ::::::::: notes -### Maßeinheit für Code-Qualität ;-) +## Maßeinheit für Code-Qualität ;-) Es gibt eine "praxisnahe" (und nicht ganz ernst gemeinte) Maßeinheit für Code-Qualität: Die "WTF/m" (_What the Fuck per minute_): @@ -184,7 +184,7 @@ in Ordnung ... ::::::::: -## Code Smells: Nichtbeachtung von Coding Conventions +# Code Smells: Nichtbeachtung von Coding Conventions * Richtlinien für einheitliches Aussehen => Andere Programmierer sollen Code schnell lesen können @@ -206,7 +206,7 @@ in Ordnung ... [[Hinweis: Genauere Betrachtung in "Coding Rules"]{.ex}]{.slides} -## Code Smells: Schlechte Kommentare I +# Code Smells: Schlechte Kommentare I * Ratlose Kommentare @@ -241,7 +241,7 @@ in Ordnung ... ::: -## Code Smells: Schlechte Kommentare II +# Code Smells: Schlechte Kommentare II * Veraltete Kommentare @@ -281,7 +281,7 @@ in Ordnung ... ::: -## Code Smells: Schlechte Namen und fehlende Kapselung +# Code Smells: Schlechte Namen und fehlende Kapselung ```java public class Studi extends Person { @@ -320,7 +320,7 @@ gehören zur Schnittstelle und damit Teil des "Vertrags" mit den Nutzern! ::: -## Code Smells: Duplizierter Code +# Code Smells: Duplizierter Code ```java public class Studi { @@ -351,7 +351,7 @@ Kopierter/duplizierter Code ist problematisch: ::: -## Code Smells: Langer Code +# Code Smells: Langer Code * Lange Klassen * Faustregel: 5 Bildschirmseiten sind viel @@ -379,7 +379,7 @@ Kopierter/duplizierter Code ist problematisch: \bigskip ::::::::: notes -### Lesbarkeit und Übersichtlichkeit leiden +## Lesbarkeit und Übersichtlichkeit leiden * Der Mensch kann sich nur begrenzt viele Dinge im Kurzzeitgedächtnis merken * Klassen, die länger als 5 Bildschirmseiten sind, erfordern viel Hin- und @@ -392,7 +392,7 @@ Kopierter/duplizierter Code ist problematisch: * Große Dateien verleiten (auch mangels Übersichtlichkeit) dazu, neuen Code ebenfalls schluderig zu gliedern -### Langer Code deutet auch auf eine Verletzung des Prinzips der Single Responsibility hin +## Langer Code deutet auch auf eine Verletzung des Prinzips der Single Responsibility hin * Klassen fassen evtl. nicht zusammengehörende Dinge zusammen @@ -440,7 +440,7 @@ Kopierter/duplizierter Code ist problematisch: ::::::::: -## Code Smells: Feature Neid +# Code Smells: Feature Neid ```java public class CreditsCalculator { @@ -466,14 +466,14 @@ public class CreditsCalculator { ::: notes -## Weiterführende Links +# Weiterführende Links * ["Foundations: Clean Code" (The Odin Project)](https://www.theodinproject.com/lessons/foundations-clean-code) * ["Documentation Best Practices" (Google Styleguide)](https://github.com/google/styleguide/blob/gh-pages/docguide/best_practices.md) ::: -## Wrap-Up +# Wrap-Up * Code entsteht nicht zum Selbstzweck => Lesbarkeit ist wichtig diff --git a/lecture/quality/tdd.md b/lecture/quality/tdd.md index c0e8a7bcb..fa615cd66 100644 --- a/lecture/quality/tdd.md +++ b/lecture/quality/tdd.md @@ -41,10 +41,10 @@ fhmedia: --- -## Design für Testbarkeit +# Design für Testbarkeit ::: notes -### Schlechtes Beispiel +## Schlechtes Beispiel ::: ```java @@ -61,7 +61,7 @@ public void ausgabe(...) { \smallskip ::: notes -### Etwas verbessertes Beispiel +## Etwas verbessertes Beispiel ::: ```java @@ -76,7 +76,7 @@ public void ausgabe(...) { } ``` -## Anzeichen für schlecht testbares Design +# Anzeichen für schlecht testbares Design * Keine Rückgabewerte * Direkte Ausgaben @@ -87,7 +87,7 @@ public void ausgabe(...) { * Seiteneffekte, z.B. Berechnung und direkte Veränderung von Zuständen **anderer** Objekte -## Private Methoden sind nicht (direkt) testbar +# Private Methoden sind nicht (direkt) testbar 1. Gar nicht testen???? @@ -131,7 +131,7 @@ public void ausgabe(...) { ::: -## Was ist ein guter Test? +# Was ist ein guter Test? * Läuft schnell. Läuft schnell. Läuft schnell!!! @@ -172,12 +172,12 @@ public void ausgabe(...) { ::: -## TDD oder der "Red-Green-Refactor"-Zyklus +# TDD oder der "Red-Green-Refactor"-Zyklus ![](images/tdd.png){width="60%" web_width="40%"} ::: notes -### Test-Driven Development (_TDD_) +## Test-Driven Development (_TDD_) 1. Schreibe Test => schlägt fehl: "Red" * Überlegen Sie, wie das Stück Software, welches Sie erstellen wollen, @@ -211,7 +211,7 @@ _Anmerkung_: Jeder Zyklus sollte sehr kurz sein! [Demo: Validierung von Passwörtern]{.ex href="https://youtu.be/4NAcu8I8fJk"} ::: notes -### Vorteile bei konsequenter Anwendung von TDD +## Vorteile bei konsequenter Anwendung von TDD * Kein ungetesteter Code mehr: Es entstehen automatisch viele Unit-Tests und gibt keinen Grund, keine Tests zu schreiben @@ -225,7 +225,7 @@ _Anmerkung_: Jeder Zyklus sollte sehr kurz sein! ::: -## Wrap-Up +# Wrap-Up * Testbarkeit muss mitgedacht werden: SW-Design * Private Methoden auch testen ("Sicherheitsnetz") diff --git a/lecture/quality/testcases.md b/lecture/quality/testcases.md index e91655226..f7dbb83e1 100644 --- a/lecture/quality/testcases.md +++ b/lecture/quality/testcases.md @@ -200,7 +200,7 @@ challenges: | --- -## Hands-On (10 Minuten): Wieviel und was muss man testen? +# Hands-On (10 Minuten): Wieviel und was muss man testen? ```java public class Studi { @@ -219,7 +219,7 @@ public class Studi { ``` ::::::::: notes -### _JEDE_ Methode mindestens testen mit/auf: +## _JEDE_ Methode mindestens testen mit/auf: * Positive Tests: Gutfall (Normalfall) => "gültige ÄK/GW" * Negativ-Tests (Fehlbedienung, ungültige Werte) => "ungültige ÄK/GW" @@ -231,7 +231,7 @@ public class Studi { => Wichtige Pfade im Code abgedeckt (White-Box)? -### Praxis +## Praxis * Je kritischer eine Klasse/Methode/Artefakt ist, um so intensiver testen! * Suche nach Kompromissen: Testkosten vs. Kosten von Folgefehlern; @@ -242,7 +242,7 @@ Grenzwertanalyse (siehe nächste Folien). Mehr dann später im Wahlfach "Softwar ::::::::: -## Äquivalenzklassenbildung +# Äquivalenzklassenbildung ::: notes Beispiel: Zu testende Methode mit Eingabewert _x_, der zw. 10 und 100 liegen soll @@ -264,7 +264,7 @@ Beispiel: Zu testende Methode mit Eingabewert _x_, der zw. 10 und 100 liegen sol ::::::::: notes -### Bemerkungen +## Bemerkungen Hintergrund: Da die Werte einer ÄK zu gleichartigem Verhalten führen, ist es egal, _welchen_ Wert man aus einer ÄK für den Test nimmt. @@ -282,7 +282,7 @@ auch die Ausgabeseite zu berücksichtigen (ist aber u.U. nur schwierig zu realisieren). -### Faustregeln bei der Bildung von ÄK +## Faustregeln bei der Bildung von ÄK * Falls eine Beschränkung einen Wertebereich spezifiziert: Aufteilung in eine gültige und zwei ungültige ÄK @@ -331,7 +331,7 @@ der laufenden Nummer $n$. ::::::::: -## ÄK: Erstellung der Testfälle +# ÄK: Erstellung der Testfälle * Jede ÄK durch _mindestens_ **einen TF** abdecken @@ -359,9 +359,9 @@ miteinander in einem TF kombiniert werden! Bei gleichzeitiger Behandlung verschi ::: -## ÄK: Beispiel: Eingabewert _x_ soll zw. 10 und 100 liegen +# ÄK: Beispiel: Eingabewert _x_ soll zw. 10 und 100 liegen -### Äquivalenzklassen +## Äquivalenzklassen | Eingabe | gültige ÄK | ungültige ÄK | |:--------|:------------------|:----------------| @@ -371,7 +371,7 @@ miteinander in einem TF kombiniert werden! Bei gleichzeitiger Behandlung verschi \bigskip \pause -### Tests +## Tests | Testnummer | 1 | 2 | 3 | |:--------------------|:-----|:----------|:----------| @@ -380,7 +380,7 @@ miteinander in einem TF kombiniert werden! Bei gleichzeitiger Behandlung verschi | Erwartetes Ergebnis | OK | Exception | Exception | -## Grenzwertanalyse +# Grenzwertanalyse ![](images/grenzwerte.png){width="60%" web_width="40%"} @@ -410,9 +410,9 @@ nicht zu überlagern.** [[Beispiel: Eingabeparameter x zw. 10 und 100]{.ex}]{.slides} -## GW: Beispiel: Eingabewert _x_ soll zw. 10 und 100 liegen +# GW: Beispiel: Eingabewert _x_ soll zw. 10 und 100 liegen -### Äquivalenzklassen +## Äquivalenzklassen | Eingabe | gültige ÄK | ungültige ÄK | |:--------|:------------------|:----------------| @@ -420,13 +420,13 @@ nicht zu überlagern.** | | | uÄK3: $100 < x$ | -### Grenzwertanalyse +## Grenzwertanalyse [Zusätzliche Testdaten:]{.notes} 9 (uÄK2o) und 10 (gÄK1u) sowie 100 (gÄK1o) und 101 (uÄK3u) \pause -### Tests +## Tests | Testnummer | 4 | 5 | 6 | 7 | |:--------------------|:------|:------|:----------|:----------| @@ -449,7 +449,7 @@ GW-Analyse erhalten: ::: notes -## Anmerkung: Analyse abhängiger Parameter +# Anmerkung: Analyse abhängiger Parameter Wenn das Ergebnis von der Kombination der Eingabewerte abhängt, dann sollte man dies bei der Äquivalenzklassenbildung berücksichtigen: Die @@ -471,7 +471,7 @@ Vergleiche @Kleuker2019, Abschnitt "4.4 Äquivalenzklassen und Objektorientierun ::: -## Wrap-Up +# Wrap-Up * Gründliches Testen ist ebenso viel Aufwand wie Coden * Äquivalenzklassenbildung und Grenzwertanalyse diff --git a/lecture/quality/testing-intro.md b/lecture/quality/testing-intro.md index dd6ae0a71..6cf612645 100644 --- a/lecture/quality/testing-intro.md +++ b/lecture/quality/testing-intro.md @@ -112,7 +112,7 @@ challenges: | --- -## Software-Fehler und ihre Folgen +# Software-Fehler und ihre Folgen ![](images/swfehler.png){width="80%"} @@ -120,7 +120,7 @@ challenges: | ::: notes -## (Einige) Ursachen für Fehler +# (Einige) Ursachen für Fehler * Zeit- und Kostendruck * Mangelhafte Anforderungsanalyse @@ -132,7 +132,7 @@ challenges: | ::: -## Irgendjemand muss mit Deinen Bugs leben! +# Irgendjemand muss mit Deinen Bugs leben! ::: notes Leider gibt es im Allgemeinen keinen Weg zu zeigen, dass eine Software korrekt ist. @@ -167,7 +167,7 @@ das Testen automatisieren. Und hier kommt JUnit ins Spiel :) ::: -## Was wann testen? Wichtigste Teststufen +# Was wann testen? Wichtigste Teststufen * **Modultest** * Testen einer Klasse und ihrer Methoden @@ -190,7 +190,7 @@ das Testen automatisieren. Und hier kommt JUnit ins Spiel :) => Verweis auf Wahlfach "Softwarequalität" -## JUnit: Test-Framework für Java +# JUnit: Test-Framework für Java ::: notes **JUnit** --- Open Source Java Test-Framework zur Erstellung und @@ -248,7 +248,7 @@ Version nicht mehr weiterentwickelt wird. ::: -## Anlegen und Organisation der Tests mit JUnit +# Anlegen und Organisation der Tests mit JUnit :::::: columns ::: {.column width="50%"} @@ -287,7 +287,7 @@ hintereinander (da sie im selben Paket sind und mit dem selben Namen anfangen) => besserer Überblick! -## Anmerkung: Die (richtige) JUnit-Bibliothek muss im Classpath liegen! +# Anmerkung: Die (richtige) JUnit-Bibliothek muss im Classpath liegen! Eclipse bringt für JUnit 4 und JUnit 5 die nötigen Jar-Dateien mit und fragt beim erstmaligen Anlegen einer neuen Testklasse, ob die für die ausgewählte Version @@ -302,7 +302,7 @@ herunter und bindet sie in das Projekt ein. ::: -## JUnit 4+5: Definition von Tests +# JUnit 4+5: Definition von Tests Annotation `@Test` vor Testmethode schreiben @@ -329,7 +329,7 @@ aufweisen => vgl. Abschnitt "Dependency Injection for Constructors and Methods" ::: -## JUnit 4: Ergebnis prüfen +# JUnit 4: Ergebnis prüfen Klasse **`org.junit.Assert`** enthält diverse **statische** Methoden zum Prüfen: @@ -354,7 +354,7 @@ Für JUnit 5 finden sich die Assert-Methoden im Package `org.junit.jupiter.api.A ::: -## Anmerkung zum statischen Import +# Anmerkung zum statischen Import ::: notes Bei normalem Import der Klasse `Assert` muss man jeweils den voll qualifizierten Namen @@ -390,7 +390,7 @@ import static packageName.className.*; ``` -## Mögliche Testausgänge bei JUnit +# Mögliche Testausgänge bei JUnit :::::: columns ::: {.column width="55%"} @@ -422,14 +422,14 @@ import static packageName.className.*; ::: notes -## Anmerkungen zu Assert +# Anmerkungen zu Assert * Pro Testmethode möglichst nur **ein** Assert verwenden! * Anderenfalls: Schlägt ein Assert fehl, wird der Rest nicht mehr überprüft ... ::: -## Wrap-Up +# Wrap-Up * Testen ist genauso wichtig wie Coden * Richtiges Testen spart Geld, Zeit, ... diff --git a/readme.md b/readme.md index a90772f50..0c2f95598 100644 --- a/readme.md +++ b/readme.md @@ -32,7 +32,7 @@ has_license: true --- -## Kursbeschreibung +# Kursbeschreibung Sie haben letztes Semester in **Prog1** die *wichtigsten* Elemente und Konzepte der Programmiersprache Java kennen gelernt. @@ -46,7 +46,7 @@ und Logging auseinander setzen. Wenn uns dabei ein Entwurfsmuster "über den Weg wir die Gelegenheit nutzen und uns dieses genauer anschauen. -## Überblick Modulinhalte +# Überblick Modulinhalte 1. Fortgeschrittene Konzepte in Java ("Classic Java") - Reguläre Ausdrücke, Annotationen, Reflection @@ -72,7 +72,7 @@ wir die Gelegenheit nutzen und uns dieses genauer anschauen. [^2]: nur als Wiederholung im Praktikum -## Team +# Team - [Carsten Gips] (Sprechstunde nach Vereinbarung) - [BC George] (Sprechstunde nach Vereinbarung) @@ -82,7 +82,7 @@ wir die Gelegenheit nutzen und uns dieses genauer anschauen. [BC George]: https://www.hsbi.de/minden/ueber-uns/personenverzeichnis/birgit-christina-george -## Kursformat +# Kursformat ![](admin/images/fahrplan.png){width="80%"} @@ -99,7 +99,7 @@ Sie *können* hierzu den Raum J101 bzw. J104 (vgl. Stundenplan) nutzen. [ILIAS]: https://www.hsbi.de/elearning/goto.php?target=crs_1486054&client_id=FH-Bielefeld -## Fahrplan +# Fahrplan Hier finden Sie einen abonnierbaren [Google Kalender] mit allen Terminen der Veranstaltung zum Einbinden in Ihre Kalender-App. @@ -219,7 +219,7 @@ Bearbeitung der Quizzes jeweils **Sa, 00:00 Uhr (Vorwoche) bis Fr, 08:00 Uhr** [ [Q09]: https://www.hsbi.de/elearning/goto.php?target=tst_1527345&client_id=FH-Bielefeld -## Prüfungsform, Note und Credits +# Prüfungsform, Note und Credits **Parcoursprüfung**, 5 ECTS (PO23) @@ -228,7 +228,7 @@ dieser Lehrveranstaltung noch keine KI-gestützten Assistenten benutzen. Lösung ganz oder teilweise unter Zuhilfenahme von KI-Unterstützung erstellt wurden, werden wie nicht abgegeben behandelt. -### Prüfung im ersten Zeitraum +## Prüfung im ersten Zeitraum 1. **Quizzes**: mind. 5 der 9 Quizzes bestanden (ohne Note/Punkte) (Einzelbearbeitung, fristgerecht bis zur jeweiligen Vorlesung, je Quiz @@ -264,7 +264,7 @@ verbessert sich die Gesamtnote um eine Teilnote. (Hinweise zur [Prüfungsvorbereitung] für Station I bis III) -### Prüfung im zweiten Zeitraum +## Prüfung im zweiten Zeitraum 1. **Station IV**: Schriftliche Prüfung (digitale Klausur) 90 Minuten in Minden im B40 @@ -273,9 +273,9 @@ verbessert sich die Gesamtnote um eine Teilnote. (Hinweise zur [Prüfungsvorbereitung] für Station IV) -## Materialien +# Materialien -### Literatur +## Literatur 1. ["**Java ist auch eine Insel**"]. Ullenboom, C., Rheinwerk-Verlag, 2021. ISBN [978-3-8362-8745-6]. @@ -291,7 +291,7 @@ verbessert sich die Gesamtnote um eine Teilnote. ["The Java Tutorials"]: https://docs.oracle.com/javase/tutorial/ ["Learn Java"]: https://dev.java/learn/ -### Tools +## Tools - JDK: **Java SE 21 (LTS)** ([Oracle] oder [Alternativen], bitte 64-bit Version nutzen) - IDE: [Eclipse IDE for Java Developers] oder [IntelliJ IDEA (Community Edition)] oder [Visual @@ -307,9 +307,9 @@ verbessert sich die Gesamtnote um eine Teilnote. [Git]: https://git-scm.com/ -## Förderungen und Kooperationen +# Förderungen und Kooperationen -### Förderung durch DH.NRW (Digi Fellowships) +## Förderung durch DH.NRW (Digi Fellowships) Die Überarbeitung dieser Lehrveranstaltung wurde vom Ministerium für Kultur und Wissenschaft (MKW) in NRW im Einvernehmen mit der Digitalen Hochschule NRW (DH.NRW) gefördert: @@ -317,7 +317,7 @@ Die Überarbeitung dieser Lehrveranstaltung wurde vom Ministerium für Kultur un ["Fellowships für Innovationen in der digitalen Hochschulbildung"]: https://www.dh.nrw/kooperationen/Digi-Fellows-2 -### Kooperation mit dem DigikoS-Projekt +## Kooperation mit dem DigikoS-Projekt Diese Vorlesung wurde vom Projekt ["Digitalbaukasten für kompetenzorientiertes Selbststudium"] (*DigikoS*) unterstützt. Ein vom DigikoS-Projekt ausgebildeter Digital Learning Scout hat @@ -330,7 +330,7 @@ von der Stiftung Innovation in der Hochschullehre gefördert. --- -## LICENSE +# LICENSE [``{=markdown}](https://creativecommons.org/licenses/by-sa/4.0/)