03 | Quarto Refactored
📝 Refactoring (auch Refaktorisierung, Refaktorierung oder Restrukturierung) bezeichnet in der Software-Entwicklung die manuelle oder automatisierte Strukturverbesserung von Quelltexten unter Beibehaltung des beobachtbaren Programmverhaltens. Dabei sollen Lesbarkeit, Verständlichkeit, Wartbarkeit und Erweiterbarkeit verbessert werden, mit dem Ziel, den jeweiligen Aufwand für Fehleranalyse und funktionale Erweiterungen deutlich zu senken. Quelle: Wikipedia
🟪 Eine abstrakte Oberklasse Figure
Die aktuellen Chamäleon-Unterklassen stellen Get-Methoden bereit, die keine Rücksicht auf die tatsächlichen Attributwerte nehmen. Streng genommen handelt es sich hierbei um eine Inkonsistenz (Widersprüchlichkeit) der Modellierung.
Durch Generalalisierung soll diese Inkonsistenz behoben werden.
📝 Man spricht von Spezialisierung, wenn man von einer Oberklasse ausgeht und erbende Unterklassen konzipiert. Manchmal sucht man aber auch die gemeinsame Struktur bestehender Klassen und konzipiert eine gemeinsame Oberklasse; das nennt man Generalisierung. In beiden Fällen ist es das Ziel, keine redundanten (= mehrfach vorhandene, im Kontext überflüssige) Strukturen zu definieren.
👤 1. Implementiere die Figur-Klassen entsprechend dem unten gegebenen UML-Diagramm.
💁 Zur Hilfe kannst du auch erst Aufgabe 2 bearbeiten.
👤 2. Analysiere den folgenden Programmcode und ergänze fehlenden Zahlen.
👾 Programmbeispiel
public class FlaechenDemo {
public static void main(String[] args) {
Flaeche[] flaechen = new Flaeche[2];
flaechen[0] = new Rechteck(4, 3);
flaechen[1] = new Kreis(2);
for (int i = 0; i < flaechen.length; i++) {
System.out.println(flaechen[i].getName() + ": " + flaechen[i].berechneFlaeche());
}
}
}
abstract class Flaeche {
private final String name;
public Flaeche(String name) {
this.name = name;
}
public String getName() {
return name;
}
public abstract double berechneFlaeche();
}
class Rechteck extends Flaeche {
private final double breite;
private final double hoehe;
public Rechteck(double breite, double hoehe) {
super("Rechteck");
this.breite = breite;
this.hoehe = hoehe;
}
public double berechneFlaeche() {
return breite * hoehe;
}
}
class Kreis extends Flaeche {
private final double radius;
public Kreis(double radius) {
super("Kreis");
this.radius = radius;
}
public double berechneFlaeche() {
return Math.PI * radius * radius;
}
}
🟦 Fachkonzept: Abstrakte Klasse
👤 3. Ergänze den Lückentext zu abstrakten Klassen.
🟩 Übungsaufgabe
👤 4. Erstelle per Hand ein Implementationsdiagramm nach den Vorgaben unten. Hinweise: Methoden müssen nicht aufgeführt werden; die Klasse Konstruktionsstein soll abstrakt sein.
Gegeben sind Duplo-Steine wie unten abgebildet. Von jedem Duplo-Teil soll eine Bezeichnung, die Farbe und die Anzahl der Noppen verwaltet werden. Folgende Arten von Doplo-Teilen sollen abgebildet werden können: Basissteine, Konstruktionssteine, Tiere und Personenfiguren. Bei einem Basissteinen muss die Information gespeichert werden, ob dieser zum (klassischen) Lego kompatibel ist, bei jeder Personenfigur wird gespeichert, ob sie den Kopf drehen kann oder nicht. Bei den Tieren wird gespeichert, ob darauf eine Personenfigur oder ein weiteres Tier reiten kann. Von den Konstruktionssteinen gibt es zwei Arten: Schienen (mit entsprechender Länge) und Platten (mit entsprechender Länge und Breite).
Foto: Ralf Roletschek, Wikimedia Commons
🟨 Eine weitere Generalisierung
In der Klasse FigureDrawer soll in der Methode drawFigure mit Hilfe von Generalisierung eine Vereinfachung vorgenommen werden:
Alter Methodenkopf: public void drawFigure(Figure figure, boolean isActive, int x, int y)
Neuer Methodenkopf: public void drawFigure(Figure figure, Board board, int x, int y)
Alter Code im Rumpf:
if(isActive) {
xPos = activeBoard.calculateCenterPoint(x, y)[0];
yPos = activeBoard.calculateCenterPoint(x, y)[1];
} else {
xPos = passiveBoard.calculateCenterPoint(x, y)[0];
yPos = passiveBoard.calculateCenterPoint(x, y)[1];
}
Neuer Code im Rumpf:
xPos = board.calculateCenterPoint(x, y)[0];
yPos = board.calculateCenterPoint(x, y)[1];
👥 1. Überlegt, welche Änderungen im Projekt nötig sind.
👥 2. Im Folgenden siehst du, wie Interfaces im Implementationsdiagramm dargestellt werden. Ergänzt den folgenden Lückentext zu Interfaces.
👥 3. Sammelt Vorteile, wann sich eher abstrakte Klassen, wann sich eher Interfaces anbieten.
🟧 Übungsaufgaben im Schulbuch
👤 S. 39 Aufgabe 8, S. 43 Aufgabe 5
Beachte die Beurteilungskriterien realitätsnahe Modellierung, strikte Datenkapselung, Codeduplizierung, klare Zuständigkeiten (Schulbuch, S. 41).