This commit is contained in:
2024-12-08 18:18:11 +01:00
parent 27b50b6b08
commit eeb8580a31
13 changed files with 833 additions and 58 deletions

60
WS2425/SWT D/P3.md Normal file
View File

@@ -0,0 +1,60 @@
Um die Implementierung der Buchverwaltung in der Version 1.0 (BuchV1) gemäß den genannten Architekturprinzipien zu bewerten, werde ich die Prinzipien nacheinander durchgehen und eine Bewertung sowie eine Begründung für jede geben.
### 1. Modularisierung
**Bewertung: 3 (in Grundzügen umgesetzt)**
**Begründung:** Die Buchverwaltung ist in mehrere Klassen unterteilt (z.B. `Buch` und `Buchverwaltung`), was eine gewisse Modularität aufweist. Allerdings könnte die Modularisierung weiter verbessert werden, indem zusätzliche Klassen für spezifische Aufgaben wie das Speichern und Laden von Daten oder die GUI-Logik erstellt werden. Derzeit sind alle Funktionalitäten in der `Buchverwaltung`-Klasse zusammengefasst, was zu einer Überlastung dieser Klasse führt.
### 2. Hierarchisierung
**Bewertung: 2 (kaum beachtet)**
**Begründung:** In der aktuellen Implementierung gibt es keine klare Hierarchisierung. Die Klassen sind weitgehend flach, und es gibt keine Nutzung von Vererbung oder Interfaces, um verschiedene Typen von Objekten oder Funktionen zu strukturieren. Eine hierarchische Struktur könnte helfen, die Beziehungen zwischen verschiedenen Klassen besser zu verdeutlichen und die Wartbarkeit zu verbessern.
### 3. Starker Zusammenhalt und schwache Kopplung
**Bewertung: 3 (in Grundzügen umgesetzt)**
**Begründung:** Die Klasse `Buch` hat einen hohen Zusammenhalt, da sie ausschließlich Buch-bezogene Daten und Methoden enthält. Allerdings ist die `Buchverwaltung`-Klasse stark gekoppelt an die GUI-Logik und die Datenpersistenz. Eine bessere Trennung der Verantwortlichkeiten (z.B. durch separate Klassen für die Datenverarbeitung und GUI) könnte die Kopplung reduzieren und die Wiederverwendbarkeit erhöhen.
### 4. Trennung von Zuständigkeiten
**Bewertung: 2 (kaum beachtet)**
**Begründung:** Die `Buchverwaltung`-Klasse übernimmt mehrere Verantwortlichkeiten, einschließlich der GUI-Interaktion und der Datenverwaltung. Dies führt zu einer unklaren Trennung von Zuständigkeiten. Eine klarere Trennung könnte erreicht werden, indem man spezifische Klassen für die GUI, die Datenbankverwaltung und die Buchlogik erstellt. Dies würde die Wartbarkeit und Testbarkeit des Codes verbessern.
### 5. Information Hiding
**Bewertung: 4 (in wesentlichen Teilen umgesetzt)**
**Begründung:** Die Implementierung nutzt private Attribute in der Klasse `Buch`, was dem Prinzip des Information Hiding entspricht. Die Methoden, die den Zugriff auf diese Attribute steuern (z.B. Getter und Setter), sind klar definiert. Allerdings könnten einige Implementierungsdetails der `Buchverwaltung`-Klasse, wie die Datenpersistenz, besser verborgen werden, um die interne Logik vor der Außenwelt zu schützen.
### Zusammenfassung
Insgesamt zeigt die Implementierung einige positive Aspekte, wie z.B. das Information Hiding und einen gewissen Grad an Modularisierung. Dennoch gibt es signifikante Verbesserungspotenziale, insbesondere hinsichtlich der Hierarchisierung und der Trennung von Zuständigkeiten. Eine Überarbeitung der Architektur könnte dazu beitragen, die Wartbarkeit, Erweiterbarkeit und Testbarkeit des Systems zu verbessern.
Die Architektur der Buchverwaltung in Version 1.0 (BuchV1) hat erhebliche Auswirkungen auf die folgenden Qualitätskriterien: Portabilität, Testbarkeit und Wiederverwendbarkeit. Ich werde jedes Kriterium einzeln betrachten und die Auswirkungen der aktuellen Architektur erläutern.
### 1. Portabilität
**Auswirkungen:**
Die Portabilität bezieht sich darauf, wie leicht eine Anwendung auf verschiedenen Plattformen und Umgebungen eingesetzt werden kann. In der aktuellen Implementierung gibt es einige positive Aspekte:
- **Unabhängigkeit von spezifischen Bibliotheken:** Die Buchverwaltung verwendet standardmäßige Java-Klassen (z.B. AWT für die GUI), die auf verschiedenen Plattformen verfügbar sind. Dadurch kann die Anwendung prinzipiell auf jedem System, das die Java Runtime Environment (JRE) unterstützt, betrieben werden.
- **Dateispeicherung:** Die Anwendung speichert Daten in einer serielle Datei, was einfach zu transportieren ist. Allerdings ist der harte Pfad zur Datei (`/Users/dwiesmann/IO/buchliste.ser`) eine Einschränkung, da er plattformabhängig ist. Dies könnte die Portabilität einschränken, da Benutzer die Pfade manuell anpassen müssten.
**Bewertung:** Die Portabilität ist gegeben, könnte aber durch flexiblere Dateipfade und die Verwendung von plattformunabhängigen Bibliotheken verbessert werden.
### 2. Testbarkeit
**Auswirkungen:**
Die Testbarkeit bezieht sich darauf, wie einfach es ist, die Software zu testen, insbesondere automatisierte Tests.
- **Eng gekoppelte Klassen:** Die starke Kopplung zwischen GUI-Logik und Datenverwaltung in der `Buchverwaltung`-Klasse erschwert Unit-Tests. Es ist schwierig, Teile der Logik isoliert zu testen, da die Benutzeroberfläche und die Geschäftslogik eng miteinander verwoben sind.
- **Mangel an Schnittstellen:** Die Verwendung von konkreten Klassen anstelle von Interfaces reduziert die Möglichkeit, Mock-Objekte für Tests zu verwenden. Dies erschwert das Testen von Abhängigkeiten und das Schreiben von Unit-Tests.
- **Ungetestete Benutzerinteraktionen:** Da die GUI-Logik direkt in die Hauptklasse integriert ist, fehlen Mechanismen, um Benutzerinteraktionen separat zu testen.
**Bewertung:** Die Testbarkeit ist eingeschränkt. Eine bessere Trennung der Zuständigkeiten und die Verwendung von Interfaces würden die Testbarkeit erheblich verbessern.
### 3. Wiederverwendbarkeit
**Auswirkungen:**
Die Wiederverwendbarkeit bezieht sich darauf, wie gut Teile der Software in anderen Kontexten oder Projekten wiederverwendet werden können.
- **Modularität:** Obwohl die `Buch`-Klasse wiederverwendbar ist, ist die `Buchverwaltung`-Klasse zu stark spezialisiert, um leicht in anderen Projekten eingesetzt zu werden. Die Kombination von GUI-Logik und Datenverwaltung in einer einzigen Klasse hindert die Wiederverwendbarkeit.
- **Fehlende generische Lösungen:** Es gibt keine allgemeinen Datenverwaltungslösungen oder -interfaces, die in anderen Anwendungen verwendet werden könnten. Eine generischere Architektur würde die Wiederverwendbarkeit erhöhen.
- **Engpass in der Erweiterbarkeit:** Die aktuelle Architektur lässt sich nur schwer anpassen oder erweitern, was die Wiederverwendbarkeit der Komponenten einschränkt. Änderungen an einer Funktionalität könnten ungewollte Auswirkungen auf andere Teile der Anwendung haben.
**Bewertung:** Die Wiederverwendbarkeit ist gering. Eine stärkere Modularität und die Trennung von Funktionalitäten könnten die Wiederverwendbarkeit der Komponenten erheblich verbessern.
### Fazit
Die Architektur der Buchverwaltung in Version 1.0 hat signifikante Auswirkungen auf die Portabilität, Testbarkeit und Wiederverwendbarkeit. Während es einige positive Aspekte gibt, wie die Verwendung von Standard-Java-Klassen, sind viele Designentscheidungen (wie starke Kopplung und mangelnde Modularität) nachteilig und könnten durch eine Überarbeitung der Architektur erheblich verbessert werden.

34
WS2425/SWT D/Ue3.md Normal file
View File

@@ -0,0 +1,34 @@
Die Wahl einer geeigneten Programmiersprache ist ein wichtiger Schritt zur Sicherstellung der Qualität eines Softwareprojekts. Im Folgenden werden die genannten Aspekte erläutert, die bei der Auswahl einer Programmiersprache berücksichtigt werden sollten:
### 1. **Strukturelemente zur Konstruktion modularer Programmeinheiten**
- **Einfluss auf die Wahl der Programmiersprache:** Die Möglichkeit, Programme in modularen Einheiten (wie Funktionen, Klassen oder Modulen) zu strukturieren, ist entscheidend für die Wartbarkeit und Wiederverwendbarkeit des Codes. Sprachen, die diese Modularität unterstützen, ermöglichen es Entwicklern, Code in kleinere, wiederverwendbare Bausteine zu zerlegen.
- **Einfluss auf die Qualität:** Modularer Code ist leichter zu verstehen, zu testen und zu warten. Er fördert auch eine saubere Trennung der Verantwortlichkeiten im Code.
- **Beispiele:** Programmiersprachen wie **Java** und **Python** unterstützen Konzepte wie Klassen, Module und Pakete, die zur modularen Strukturierung beitragen.
### 2. **Typsystem mit strenger Typprüfung**
- **Einfluss auf die Wahl der Programmiersprache:** Ein strenges Typsystem hilft dabei, Fehler frühzeitig während der Kompilierungsphase zu erkennen, bevor der Code ausgeführt wird. Sprachen mit statischer Typisierung ermöglichen es, viele Fehler zu verhindern, die sonst zur Laufzeit auftreten könnten.
- **Einfluss auf die Qualität:** Eine strenge Typprüfung erhöht die Zuverlässigkeit des Codes und reduziert das Risiko von Laufzeitfehlern. Sie verbessert auch die Lesbarkeit und Dokumentation des Codes, da der Datentyp explizit definiert ist.
- **Beispiele:** **C++** und **Java** sind Beispiele für Programmiersprachen mit einem starken, statischen Typsystem. Im Gegensatz dazu ist **Python** dynamisch typisiert, was flexibler ist, aber mehr Laufzeitfehler verursachen kann.
### 3. **Trennung von Schnittstelle und Implementierung**
- **Einfluss auf die Wahl der Programmiersprache:** Eine klare Trennung von Schnittstelle (was der Code tut) und Implementierung (wie er es tut) ermöglicht eine einfachere Wartung und Anpassung des Codes. Dies ist besonders wichtig bei der Entwicklung großer Softwaresysteme.
- **Einfluss auf die Qualität:** Durch diese Trennung können Entwickler Änderungen an der Implementierung vornehmen, ohne die Schnittstelle zu ändern, was die Kompatibilität mit anderen Modulen bewahrt.
- **Beispiele:** In **Java** können Interfaces verwendet werden, um Schnittstellen zu definieren, während die Implementierung in Klassen erfolgt. **C++** verwendet Header-Dateien für die Deklaration und Implementierungsdateien für die Definition.
### 4. **Syntax, die zur Lesbarkeit des Codes beiträgt**
- **Einfluss auf die Wahl der Programmiersprache:** Eine klare und einfache Syntax verbessert die Lesbarkeit des Codes, was wiederum die Fehleranfälligkeit reduziert und die Zusammenarbeit im Team erleichtert.
- **Einfluss auf die Qualität:** Gut lesbarer Code ist leichter zu verstehen und zu warten, insbesondere wenn mehrere Entwickler an einem Projekt arbeiten.
- **Beispiele:** **Python** ist für seine einfache und klare Syntax bekannt, die der Lesbarkeit sehr zugutekommt. Im Gegensatz dazu kann **Perl** durch seine flexiblere, aber auch komplexere Syntax schwerer lesbar sein.
### 5. **Automatische Zeigerverwaltung**
- **Einfluss auf die Wahl der Programmiersprache:** Die automatische Speicherverwaltung, wie sie durch Garbage Collection bereitgestellt wird, hilft, Speicherlecks und andere Speicherverwaltungsprobleme zu vermeiden.
- **Einfluss auf die Qualität:** Durch die automatische Verwaltung von Speicherressourcen wird die Anzahl der Speicherverwaltungsfehler reduziert, was die Zuverlässigkeit und Stabilität der Software erhöht.
- **Beispiele:** **Java** und **Python** haben automatische Garbage Collection, während **C++** eine manuelle Speicherverwaltung erfordert, was mehr Flexibilität bietet, aber auch fehleranfälliger ist.
### 6. **Gute Unterstützung durch Werkzeuge**
- **Einfluss auf die Wahl der Programmiersprache:** Eine breite Unterstützung durch Entwicklungswerkzeuge wie IDEs, Debugger, und statische Analysewerkzeuge erleichtert die Entwicklung und das Debugging des Codes.
- **Einfluss auf die Qualität:** Durch leistungsfähige Werkzeuge können Entwickler effizienter arbeiten, Fehler schneller finden und beheben sowie die Qualität des Codes durch automatisierte Tests und Code-Analysen verbessern.
- **Beispiele:** **Java** hat eine starke Unterstützung durch Entwicklungsumgebungen wie IntelliJ IDEA und Eclipse. Für **Python** gibt es ebenfalls viele Werkzeuge wie PyCharm und Visual Studio Code.
### Zusammenfassung
Die Wahl der Programmiersprache kann einen erheblichen Einfluss auf die Qualität der Software haben. Kriterien wie Modularität, Typprüfung, Trennung von Schnittstelle und Implementierung, lesbare Syntax, automatische Speicherverwaltung und Unterstützung durch Werkzeuge tragen zur Wartbarkeit, Erweiterbarkeit und Zuverlässigkeit des Codes bei. Durch die sorgfältige Berücksichtigung dieser Aspekte können Entwickler die Sprachwahl so treffen, dass sie die langfristige Qualität und Effizienz der Softwareentwicklung fördern.

63
WS2425/SWT D/Ue6.md Normal file
View File

@@ -0,0 +1,63 @@
Um die Queue zu testen, beschreiben wir verschiedene Testfälle. Bei einer Arraylänge von 3 können wir den Speicherplatz optimal nutzen, indem wir das Verhalten des Ringspeichers in verschiedenen Zuständen der Queue (voll, leer, teilweise gefüllt) prüfen. Wir definieren die Eingaben, die erwarteten Rückgabewerte sowie den logischen Zustand des Arrays für jeden Testfall.
### Testfälle
1. **Testfall 1: Enqueue in eine leere Queue**
- **Aktion:** `enqueue(1)`
- **Erwartetes Ergebnis:** Keine Rückgabe.
- **Array-Zustand:** `[1, -, -]`
2. **Testfall 2: Zweiter Wert wird hinzugefügt**
- **Aktion:** `enqueue(2)`
- **Erwartetes Ergebnis:** Keine Rückgabe.
- **Array-Zustand:** `[1, 2, -]`
3. **Testfall 3: Dritter Wert wird hinzugefügt (Queue voll)**
- **Aktion:** `enqueue(3)`
- **Erwartetes Ergebnis:** Keine Rückgabe.
- **Array-Zustand:** `[1, 2, 3]`
4. **Testfall 4: Dequeue von voller Queue**
- **Aktion:** `dequeue()`
- **Erwarteter Rückgabewert:** `1`
- **Array-Zustand:** `[-, 2, 3]`
5. **Testfall 5: Enqueue bei fast voller Queue**
- **Aktion:** `enqueue(4)`
- **Erwartetes Ergebnis:** Keine Rückgabe.
- **Array-Zustand:** `[4, 2, 3]` (da das Array als Ring organisiert ist, wird 4 am Anfang gespeichert)
6. **Testfall 6: Dequeue**
- **Aktion:** `dequeue()`
- **Erwarteter Rückgabewert:** `2`
- **Array-Zustand:** `[4, -, 3]`
7. **Testfall 7: Enqueue, um die Queue zu füllen**
- **Aktion:** `enqueue(5)`
- **Erwartetes Ergebnis:** Keine Rückgabe.
- **Array-Zustand:** `[4, 5, 3]`
8. **Testfall 8: Enqueue, das Überschreiben auslöst**
- **Aktion:** `enqueue(6)`
- **Erwartetes Ergebnis:** Keine Rückgabe.
- **Array-Zustand:** `[4, 5, 6]` (ältester Wert `3` wurde überschrieben)
9. **Testfall 9: Dequeue nach Überschreiben**
- **Aktion:** `dequeue()`
- **Erwarteter Rückgabewert:** `4`
- **Array-Zustand:** `[-, 5, 6]`
10. **Testfall 10: Weiteres Dequeue**
- **Aktion:** `dequeue()`
- **Erwarteter Rückgabewert:** `5`
- **Array-Zustand:** `[-, -, 6]`
11. **Testfall 11: Letztes Dequeue zum Leeren der Queue**
- **Aktion:** `dequeue()`
- **Erwarteter Rückgabewert:** `6`
- **Array-Zustand:** `[-, -, -]` (Queue ist jetzt leer)
12. **Testfall 12: Dequeue von leerer Queue**
- **Aktion:** `dequeue()`
- **Erwartetes Ergebnis:** Fehler wird signalisiert, da die Queue leer ist.