Skip to content

Commit

Permalink
Merge pull request #4 from fabiandudler/main
Browse files Browse the repository at this point in the history
fix typos and link to blog
  • Loading branch information
marcelluethi authored Oct 3, 2023
2 parents 20a44d9 + 57f28b2 commit b4e9395
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 60 deletions.
20 changes: 8 additions & 12 deletions docs/exercises/jabref-extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
```
Expand Down Expand Up @@ -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.
Expand All @@ -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(<ClassName>.class);``` instantiiert werden kann. Es sollte jedoch ```LoggerFactory.getLogger(<ClassName>.class)``` sein.

Expand Down Expand Up @@ -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.

Expand All @@ -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).
21 changes: 6 additions & 15 deletions docs/week5/exercises/atm-scenario.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.


Expand Down
6 changes: 3 additions & 3 deletions docs/week5/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
41 changes: 11 additions & 30 deletions docs/week5/oo-composition-vs-inheritance.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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.

Expand All @@ -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.



Expand All @@ -88,14 +74,9 @@ public class CountingList<T> extends ArrayList<T> {
}
}
```
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
Expand Down

0 comments on commit b4e9395

Please sign in to comment.