diff --git a/docs/exercises/jabref-extension.md b/docs/exercises/jabref-extension.md index 43a9251..4e74ef7 100644 --- a/docs/exercises/jabref-extension.md +++ b/docs/exercises/jabref-extension.md @@ -6,21 +6,21 @@ title : Woche 5 * Dieses Übungsblatt muss bis spätestens 25. Oktober, 23.59 bearbeitet und via Pull Request abgegeben werden. -* Wir empfehlen, diese Übungsblatt in Zweiergruppen zu bearbeiten (siehe Abgabeinstruktionen am Ende dieses Dokuments) +* Wir empfehlen, dieses Übungsblatt in Zweiergruppen zu bearbeiten (siehe Abgabeinstruktionen am Ende dieses Dokuments). ## Einführung In dieser Übung werden Sie eine komplette (jedoch sinnfreie) Erweiterung an Jabref vornehmen. -Ihre Erweiterung soll erkennen, dass ein Paper vom Autor "Fred Brooks" zur Datenbank hinzugefügt wurde. Wenn das Paper hinzugefügt wird soll eine Dialogbox angezeigt werden. -Diese Funktion soll sich via den *Preferences* an und ausschalten lassen. +Ihre Erweiterung soll erkennen, dass ein Paper vom Autor "Fred Brooks" zur Datenbank hinzugefügt wurde. Wenn das Paper hinzugefügt wird, soll eine Dialogbox angezeigt werden. +Diese Funktion soll sich via den *Preferences* an- und ausschalten lassen. In den folgenden Aufgaben entwickeln Sie diese Erweiterung Schritt für Schritt. ## Aufgabe 0: Vorbereitung -#### Erstellen eines Feature branch +#### Erstellen eines Featurebranch Da wir die Änderungen der letzten Übung hier nicht benötigen, starten wir wieder vom Main branch. ``` @@ -53,8 +53,7 @@ Lesen Sie auch die [High-Level Dokumentation](https://jabref.readthedocs.io/en/l ## Aufgabe 1: Arbeiten mit dem Eventbus In dieser Aufgabe nutzen Sie den EventBus. Erstellen Sie eine neue Klasse ```BrooksHandler``` in einem neuen Package ```org.jabref.gui.sillyextensions```. -Diese Klasse soll auf auf Events vom Typ ```EntriesAddedEvent``` und ```EntryChangedEvent``` reagieren. Wenn immer ein solches Event von Jabref generiert wird, soll -die Meldung "Entries Added" sowie der Titel des entsprechenden Eintrags auf der Konsole (mit ```System.out.println```) ausgebgeben werden. +Diese Klasse soll auf auf Events vom Typ ```EntriesAddedEvent``` und ```EntryChangedEvent``` reagieren. Wenn immer ein solches Event von Jabref generiert wird, soll die Meldung "Entries Added" sowie der Titel des entsprechenden Eintrags auf der Konsole (mit ```System.out.println```) ausgebgeben werden. *Tipp:* Als Vorlage schauen Sie sich an, wie dies für die Klasse ```CitationStyleCache``` implementiert ist. Nutzen Sie auch die Funktion *Find Usages*, die Sie durch das Context Menu in Intellij erreichen können um herauszufinden, wo eine bestimmte Funktionalität benutzt wird. @@ -70,8 +69,7 @@ In einem realen Projekt wollen Sie nicht Meldungen mit ```System.out.println``` Schauen Sie sich danach die Datei ```tinylog.properties``` an, die Sie im Verzeichnis ```src\main\resources\``` finden. In dieser Datei können Sie den Logging Level verändern. -Setzen Sie den Logging Level ```Info``` auf ```Debug```? Schauen Sie sich die Meldungen an, die -auf die Konsole ausgegeben werden, wenn Sie JabRef start. Was beobachten Sie? +Setzen Sie den Logging Level ```Info``` auf ```Debug```? Schauen Sie sich die Meldungen an, die auf die Konsole ausgegeben werden, wenn Sie JabRef starten. Was beobachten Sie? *Hinweis:* In der Dokumentation steht, dass der Logger mittels ```LogFactory.getLog(.class);``` instantiiert werden kann. Es sollte jedoch ```LoggerFactory.getLogger(.class)``` sein. @@ -100,8 +98,7 @@ Committen Sie Ihre Änderungen. Fügen Sie eine neue Checkbox *Scan for Brooks* im Preferences Dialog hinzu. -*Tipp:* Orientieren Sie sich an der Einstellung ```showAdvancedHints```. Suchen Sie die Stellen im Code wo etwas für diese Einstellung gemacht wird und imitieren Sie den -Code. +*Tipp:* Orientieren Sie sich an der Einstellung ```showAdvancedHints```. Suchen Sie die Stellen im Code wo etwas für diese Einstellung gemacht wird und imitieren Sie den Code. Committen Sie Ihre Änderungen. @@ -118,5 +115,4 @@ Die Abgabe der Übung erfolgt durch push vom entsprechenden Branch: git push origin uebung5 ``` und entsprechenden Pull Request. Geben Sie hier den Ihnen zugeordneten Reviewer (siehe [diese Liste](https://adam.unibas.ch/goto_adam_file_1659074_download.html)) an. -Wenn Sie zu zweit gearbeitet haben, fügen Sie bitte ihre(n) Partner(in) als *Assignee* hinzu -(eventuell müssen Sie in den Einstellungen noch Zugriff erteilen). +Wenn Sie zu zweit gearbeitet haben, fügen Sie bitte ihre(n) Partner(in) als *Assignee* hinzu (eventuell müssen Sie in den Einstellungen noch Zugriff erteilen). diff --git a/docs/week5/exercises/atm-scenario.md b/docs/week5/exercises/atm-scenario.md index 79522f3..9e5e9da 100644 --- a/docs/week5/exercises/atm-scenario.md +++ b/docs/week5/exercises/atm-scenario.md @@ -5,32 +5,23 @@ title : Woche 5 # Bankomat Szenario Die Software die geschrieben werden muss, simuliert die Funktionalität eines -Bankomaten. Der Bankomat hat einen Kartenleser und ein Fach um Geld (d.h. Banknoten) einzuzahlen sowie ein Geldausgabefach. Der Kunde interagiert via einer Konsole bestehend aus Tastatur -und Display. Im Innern des Bankomaten befindet sich ein Drucker um Quittungen zu -drucken. +Bankomaten. Der Bankomat hat einen Kartenleser und ein Fach um Geld (d.h. Banknoten) einzuzahlen sowie ein Geldausgabefach. Der Kunde interagiert via einer Konsole bestehend aus Tastatur und Display. Im Innern des Bankomaten befindet sich ein Drucker um Quittungen zu drucken. Der Bankomat kommuniziert mit dem Bankensystem via einem Kommunikationslink. -Zu jedem Zeitpunkt kann nur 1 Kunde bedient werden. Ein Kunde muss seine Bankkarte in den -Kartenleser einführen und einen Pin eingeben. Die Information auf der Karte sowie der -Pin wird, als Teil einer Transaktion, zur Prüfung an die Bank gesendet. +Zu jedem Zeitpunkt kann nur ein Kunde bedient werden. Ein Kunde muss seine Bankkarte in den Kartenleser einführen und einen Pin eingeben. Die Information auf der Karte sowie der Pin wird, als Teil einer Transaktion, zur Prüfung an die Bank gesendet. -Der Kunde kann dann verschiedene Transaktionen ausführen. Die Karte bleibt -im Bankomaten bis der Kunde keine weiteren Transaktionen mehr ausführen will. +Der Kunde kann dann verschiedene Transaktionen ausführen. Die Karte bleibt im Bankomaten bis der Kunde keine weiteren Transaktionen mehr ausführen will. Zu diesem Zeitpunkt wird die Karte zurückgegeben. Ein Bankomat bietet folgende Dienstleistungen an: * Ein Kunde kann Geld von einem Konto (dem Konto das auf der Karte codiert ist) abheben. Bevor das Geld ausgegeben wird, muss die Bank prüfen ob genügend Geld vorhanden ist. Das Geld wird via das Geldausgabefach ausgegeben. -* Ein Kunde kann Geld auf das Konto einzahlen. Dazu wird das Geld in das Einzahlungsfach gelegt. Das Geld wird automatisch vom Bankomaten gezählt. Wenn das Geld auf Echtheit geprüft -wurde und als korrekt erkannt wurde, wird das Geld auf das Konto einbezahlt. +* Ein Kunde kann Geld auf das Konto einzahlen. Dazu wird das Geld in das Einzahlungsfach gelegt. Das Geld wird automatisch vom Bankomaten gezählt. Wenn das Geld auf Echtheit geprüft wurde und als korrekt erkannt wurde, wird das Geld auf das Konto einbezahlt. * Ein Kunde kann den Kontostand abfragen. * Jede Transaktion kann vom Kunden zu jeder Zeit abgebrochen werden. -* Jede Transaktion wird an die Bank kommuniziert und nur abgeschlossen, nachdem sie von der Bank -freigegeben wird. -* Falls der Pin (von der Bank) als falsch beurteilt wird, muss der Kunde den Pin nochmals eingeben. Nach drei Fehlversuchen wird die Karte eingezogen. Der Kunde muss dann die Bank -kontaktieren. +* Jede Transaktion wird an die Bank kommuniziert und nur abgeschlossen, nachdem sie von der Bank freigegeben wird. +* Falls der Pin (von der Bank) als falsch beurteilt wird, muss der Kunde den Pin nochmals eingeben. Nach drei Fehlversuchen wird die Karte eingezogen. Der Kunde muss dann die Bank kontaktieren. * Falls die Transaktion aus anderem Grund fehlschlägt, wird dem Kunde eine Fehlermeldung angezeigt. Der Kunde wird dann gefragt, ob er eine andere Transaktion machen möchte. - * Am Ende der Transaktion wird dem Kunden eine Quittung ausgedruckt. Auf der Quittung wird für jede Transaktion eine kurze Beschreibung (mit Zeit/Datum und Name) ausgedruckt. Am Ende wir der neue Kontostand ausgedruckt. diff --git a/docs/week5/index.md b/docs/week5/index.md index f2ed007..7469e95 100644 --- a/docs/week5/index.md +++ b/docs/week5/index.md @@ -17,8 +17,8 @@ Als Vorbereitung für die Vorlesungsstunde in dieser Woche bearbeiten Sie bitte * Schritt 2: Lesen Sie den Artikel "Vererbung und Objektkomposition" ([Artikel](./oo-composition-vs-inheritance.html)) * Schritt 3: Lesen Sie den Artikel zum Thema "Designheuristiken" ([Artikel](./oo-design-heuristics)) * Schritt 4: Schauen Sie das Video zu den "SOLID Prinzipien" an ([Video](https://unibas.cloud.panopto.eu/Panopto/Pages/Viewer.aspx?id=aa0ba520-7e28-4ad8-b112-b06700bf7364), [Slides](./slides/OO-Solid.pdf)) -* Schritt 5a: Schauen Sie sich die Slides zum Talk von Dan North, [Why Every single element of SOLID is wrong](https://speakerdeck.com/tastapod/why-every-element-of-solid-is-wrong?slide=20), an. -* Schritt 5b: Lesen Sie die Ausführungen von Dan North auf [seinem Blog](https://speakerdeck.com/tastapod/why-every-element-of-solid-is-wrong?slide=18) +* Schritt 5a: Schauen Sie sich die Slides zum Talk von Dan North, [Why Every single element of SOLID is wrong](https://speakerdeck.com/tastapod/why-every-element-of-solid-is-wrong), an. +* Schritt 5b: Lesen Sie die Ausführungen von Dan North auf [seinem Blog](https://dannorth.net/cupid-the-back-story/) * Schritt 6: Bearbeiten Sie den Test. ([Adam](https://adam.unibas.ch/goto_adam_tst_1629488.html)). #### Präsenzveranstaltung vom 18. Oktober @@ -47,6 +47,6 @@ Die Teilnehmer*innen - kennen die Merkmale und Mechanismen, der Objektorientierung und können diese anwenden - können die grundlegenden Ideen der Objektorientierung in den Kontext vom Moduldesign setzen -- Anhand eines Szenarios Kandidaten für Module/Klassen identifizieren +- können anhand eines Szenarios Kandidaten für Module/Klassen identifizieren - können die SOLID Prinzipien im Kontext der allgemeineren Software-Engineering Prinzipien setzen - kennen die SOLID Prinzipien und können Code auf deren Umsetzung analysieren diff --git a/docs/week5/oo-composition-vs-inheritance.md b/docs/week5/oo-composition-vs-inheritance.md index 627915b..8e81d13 100644 --- a/docs/week5/oo-composition-vs-inheritance.md +++ b/docs/week5/oo-composition-vs-inheritance.md @@ -4,14 +4,11 @@ title : Woche 5 --- # Vererbung und Objektkomposition -*Neben der "uses" und der "is_composed_of" Beziehung, spielt in der -objektorientierten Programmierung noch eine andere Beziehung eine vermeintlich wichtige Rolle, -nämlich die "inherits_from" Beziehung. In diesem Artikel schauen wir uns diese Beziehung näher an.* +*Neben der "uses" und der "is_composed_of" Beziehung, spielt in der objektorientierten Programmierung noch eine andere Beziehung eine vermeintlich wichtige Rolle, nämlich die "inherits_from" Beziehung. In diesem Artikel schauen wir uns diese Beziehung näher an.* ## Die "inherits_from" Beziehung -Gegeben zwei Module (Klassen) A und B. Objektorientierte Programmiersprachen geben uns -ein Sprachkonstrukt um die Beziehung B "inherits_from" A zu definieren. +Gegeben zwei Module (Klassen) A und B. Objektorientierte Programmiersprachen geben uns ein Sprachkonstrukt um die Beziehung B "inherits_from" A zu definieren. Wir sagen, *Klasse B spezialisiert Klasse A*, oder *Klasse A generalisiert Klasse B*. In diesem Kontext wird A auch als Superklasse und B als Subklasse bezeichnet. Diese Beziehung bedeutet, dass das Modul B alle Eigenschaften von Modul A hat sowie alle Funktionalität auch anbietet, @@ -28,8 +25,7 @@ class Employee { public void fire() { /* Implementation */ }; } ``` -Die hier modellierten Attribute gelten für alle Mitarbeiter. Nun gibt es jedoch verschiedene -Arten von Mitarbeitern, die jeweils noch zusätzliche Eigenschaften haben. +Die hier modellierten Attribute gelten für alle Mitarbeiter. Nun gibt es jedoch verschiedene Arten von Mitarbeitern, die jeweils noch zusätzliche Eigenschaften haben. Mittels Vererbung können wir nun diese zusätzlichen Eigenschaften modellieren, indem wir die allgemeinen Eigenschaften, die wir bereits in der Klasse ```Employee``` definiert haben, erben. @@ -46,23 +42,13 @@ class TecnicalStaff extends Employee { ## Schnittstellenvererbung und Implementationsvererbung -Die meisten objektorientierten Programmiersprachen unterstützen zwei Varianten des -Vererbungskonzepts. Die erste Variante ist die *Schnittstellenvererbung*. Dabei wird bei -der Vererbung einfach garantiert, dass die Subklasse alle Methoden und Attribute, die in der -Schnittstelle definiert sind, unterstützt. Es werden jedoch keine Implementationen von der -Superklasse vererbt. In der Programmiersprache Java wird Schnittstellenvererbung durch das Konstrukt ```Interface``` unterstützt, dass dann -von den Klassen implementiert wird. Dieses Konzept ist enorm wichtig und führt zu flexiblem und einfach zu erweiterbarem Code. +Die meisten objektorientierten Programmiersprachen unterstützen zwei Varianten des Vererbungskonzepts. Die erste Variante ist die *Schnittstellenvererbung*. Dabei wird bei der Vererbung einfach garantiert, dass die Subklasse alle Methoden und Attribute, die in der +Schnittstelle definiert sind, unterstützt. Es werden jedoch keine Implementationen von der Superklasse vererbt. In der Programmiersprache Java wird Schnittstellenvererbung durch das Konstrukt ```Interface``` unterstützt, dass dann von den Klassen implementiert wird. Dieses Konzept ist enorm wichtig und führt zu flexiblem und einfach zu erweiterbarem Code. -Bei der *Implementationsvererbung* wird zusätzlich auch die Implementation der Superklasse -mitvererbt. Die Subklasse muss also nur noch eine Implementation für die neuen, nicht bereits -in der Superklasse implementierten Methoden, bereitstellen. +Bei der *Implementationsvererbung* wird zusätzlich auch die Implementation der Superklasse mitvererbt. Die Subklasse muss also nur noch eine Implementation für die neuen, nicht bereits in der Superklasse implementierten Methoden, bereitstellen. -Auf den ersten Blick erscheint die Implementationsvererbung eine gute Idee zu sein. Die -Subklasse muss weniger Code implementieren und entsprechend sollten weniger Fehler passieren. -Leider führt die Implementationsvererbung aber auch zu einer starken Kopplung der Subklasse -an die Superklasse, da durch diese Art der Vererbung Implementationsdetails der Superklasse -mitvererbt werden. Das Prinzip vom *Information Hiding* wird hier also verletzt. Deshalb -wird häufig davon abgeraten, diese Art der Vererbung zu verwenden. +Auf den ersten Blick erscheint die Implementationsvererbung eine gute Idee zu sein. Die Subklasse muss weniger Code implementieren und entsprechend sollten weniger Fehler passieren. +Leider führt die Implementationsvererbung aber auch zu einer starken Kopplung der Subklasse an die Superklasse, da durch diese Art der Vererbung Implementationsdetails der Superklasse mitvererbt werden. Das Prinzip vom *Information Hiding* wird hier also verletzt. Deshalb wird häufig davon abgeraten, diese Art der Vererbung zu verwenden. @@ -88,14 +74,9 @@ public class CountingList extends ArrayList { } } ``` -Die Idee hier war offensichtlich, dass die Klasse ```CountingList``` die Klasse ```ArrayList``` so erweitert, dass bei jedem Aufruf der Methode ```add``` ein -Zähler inkrementiert wird. Leider funktioniert die Methode nicht, wie wir uns -das vorstellen. Wenn wir ```addAll``` aufrufen, wird jedes Element zweimal gezählt. -Der Grund dafür ist, dass in der Superklasse ```ArrayList```, die Methode ```addAll``` -so implementiert ist, dass für jedes Element die Methode ```add``` aufgerufen wird. -Somit zählen wir die Elemente zweimal. Wie die Methode ```addAll``` von der Superklasse -implementiert wird, ist jedoch ein Implementationsdetail, dass uns in der Subklasse -nicht interessieren dürfte. +Die Idee hier war offensichtlich, dass die Klasse ```CountingList``` die Klasse ```ArrayList``` so erweitert, dass bei jedem Aufruf der Methode ```add``` ein Zähler inkrementiert wird. Leider funktioniert die Methode nicht, wie wir uns das vorstellen. Wenn wir ```addAll``` aufrufen, wird jedes Element zweimal gezählt. +Der Grund dafür ist, dass in der Superklasse ```ArrayList```, die Methode ```addAll``` so implementiert ist, dass für jedes Element die Methode ```add``` aufgerufen wird. +Somit zählen wir die Elemente zweimal. Wie die Methode ```addAll``` von der Superklasse implementiert wird, ist jedoch ein Implementationsdetail, dass uns in der Subklasse nicht interessieren dürfte. Eine bessere Lösung ist die folgende, die durch Komposition von Objekten erreicht wird. ```java