Lektion 21 - Klassendiagramme
Klassen sichtbar planen
Klassendiagramme zeigen, welche Klassen ein Programm hat, welche Attribute und Methoden sie besitzen und wie sie miteinander verbunden sind. Sie helfen dir, OOP zu planen, bevor du Dart-Code schreibst.
1. Warum Klassendiagramme?
Wenn ein Projekt groesser wird, reicht es nicht mehr, einfach loszuschreiben. Klassendiagramme machen sichtbar, welche Objekte du brauchst und welche Verantwortung jedes Objekt hat.
2. Aufbau einer Klasse im Diagramm
Eine Klasse wird meistens als Rechteck mit drei Bereichen dargestellt: Klassenname, Attribute und Methoden.
+--------------------------+
| User |
+--------------------------+
| - name: String |
| - age: int |
+--------------------------+
| + introduce(): void |
| + isAdult(): bool |
+--------------------------+
Oben steht der Klassenname. In der Mitte stehen Attribute. Unten stehen Methoden.
3. Sichtbarkeit: plus, minus und hash
Klassendiagramme zeigen oft, wie sichtbar ein Attribut oder eine Methode ist.
+public: von aussen erreichbar-private: nur innerhalb der Klasse gedacht#protected: in manchen Sprachen fuer Unterklassen sichtbar
Dart nutzt fuer private Namen einen Unterstrich, zum Beispiel _balance.
Das passt im Diagramm gut zu - balance: double.
4. Attribute darstellen
Attribute beschreiben, welche Daten ein Objekt speichert. Im Diagramm notierst du Namen und Typ.
- title: String
- points: int
- isCompleted: bool
- tags: List<String>
Daraus kann in Dart zum Beispiel diese Klasse entstehen:
class LearningTask {
String title;
int points;
bool isCompleted;
List<String> tags;
LearningTask(this.title, this.points, this.isCompleted, this.tags);
}
5. Methoden darstellen
Methoden werden mit Name, Parametern und Rueckgabetyp notiert.
+ complete(): void
+ addPoints(amount: int): void
+ totalScore(): int
+ formatTitle(prefix: String): String
Als Dart-Code sieht das Prinzip so aus:
class LearningTask {
String title;
int points;
bool isCompleted = false;
LearningTask(this.title, this.points);
void complete() {
isCompleted = true;
}
String formatTitle(String prefix) {
return '$prefix: $title';
}
}
6. Assoziation: Klassen kennen sich
Eine Assoziation bedeutet: Eine Klasse kennt oder nutzt eine andere Klasse. Beispiel: Ein Kurs hat Lektionen.
Course 1 -------- * Lesson
Das bedeutet: Ein Course kann viele Lesson-Objekte besitzen oder
referenzieren.
class Course {
String title;
List<Lesson> lessons;
Course(this.title, this.lessons);
}
7. Multiplizitaet lesen
Multiplizitaet sagt, wie viele Objekte an einer Beziehung beteiligt sein koennen.
1Genau ein Objekt0..1Keins oder eins*Beliebig viele1..*Mindestens einsStudent * -------- 1 Course
Viele Students gehoeren zu einem Course.
8. Vererbung im Klassendiagramm
Vererbung wird meist mit einer Linie und einem leeren Dreieck zur Oberklasse dargestellt. In Textform kannst du es so lesen:
Student ----|> Person
Teacher ----|> Person
Das bedeutet: Student ist eine spezielle Person und
Teacher ist ebenfalls eine spezielle Person.
class Person {
String name;
Person(this.name);
}
class Student extends Person {
String course;
Student(String name, this.course) : super(name);
}
9. Komposition und Aggregation
Komposition und Aggregation zeigen Teil-Ganzes-Beziehungen. Der Unterschied ist: Bei Komposition ist das Teil stark an das Ganze gebunden. Bei Aggregation kann das Teil unabhaengiger existieren.
Quiz <>-------- Question (Komposition)
Team o--------- Person (Aggregation)
Wenn die Symbole schwer sind, reicht beim Lernen oft eine klare Beschriftung: "Quiz hat Questions" oder "Team nutzt Persons".
10. Beispiel: Coding-Lernsystem
Fuer unser Lernsystem koennte ein erstes Klassendiagramm so aussehen:
+-----------------------+
| Course |
+-----------------------+
| - title: String |
| - lessons: List<Lesson> |
+-----------------------+
| + addLesson(lesson): void |
| + lessonCount(): int |
+-----------------------+
Course 1 -------- * Lesson
+-----------------------+
| Lesson |
+-----------------------+
| - title: String |
| - topic: String |
| - tasks: List<Task> |
+-----------------------+
| + addTask(task): void |
+-----------------------+
Lesson 1 -------- * Task
+-----------------------+
| Task |
+-----------------------+
| - description: String |
| - points: int |
+-----------------------+
| + solve(): void |
+-----------------------+
Daraus erkennt man: Ein Kurs hat mehrere Lektionen. Eine Lektion hat mehrere Aufgaben. Eine Aufgabe hat Beschreibung, Punkte und eine Methode zum Bearbeiten.
11. Vom Klassendiagramm zu Dart-Code
Der Weg ist immer aehnlich: Erst Klassenname, dann Attribute, dann Konstruktor, dann Methoden.
class Course {
String title;
List<Lesson> lessons;
Course(this.title, this.lessons);
void addLesson(Lesson lesson) {
lessons.add(lesson);
}
int lessonCount() {
return lessons.length;
}
}
Ein gutes Diagramm nimmt dir nicht das Denken ab, aber es gibt dir eine klare Richtung.
12. Typische Fehler
13. Aufgaben zu Klassendiagrammen
- Zeichne ein Klassendiagramm fuer
Person,StudentundTeacher. - Markiere Vererbung mit
Student ----|> PersonundTeacher ----|> Person. - Plane ein Lernsystem mit
Course,LessonundTask. - Notiere zu jeder Klasse mindestens zwei Attribute und eine Methode.
- Schreibe danach Dart-Code fuer eine der geplanten Klassen.
Planung:
Waehle Thema: Lernsystem
Sammle Nomen aus der Beschreibung
Course
Lesson
Task
Pruefe fuer jedes Nomen:
Ist es eine Klasse?
Welche Attribute braucht sie?
Welche Methoden braucht sie?
Zeichne Beziehungen:
Course hat viele Lessons
Lesson hat viele Tasks
Schreibe danach Dart-Code fuer Course
Weiter zu Operator Overloading