Objektorientierte Programmierung
LVA 185.162, VL 2.0, 2009 W

Hinweise zur Beurteilung der 4. Übungsaufgabe

Einleitung:

Die vorläufige Beurteilung der 4. Aufgabe (reguläre Abgabe) ist für viele Gruppen eher schlecht ausgefallen. Diese Seite soll die häufigsten und wichtigsten Fehler, die dabei gemacht wurden, aufzeigen, weitere Hinweise zum Erkennen und Vermeiden der Fehler geben, wahrscheinliche Gründe für das Zustandekommen der Fehler erklären und das Beurteilungsschema kurz erläutern.

Bei einer nachträglichen Abgabe ist zu beachten, dass die Beanstandung konkreter Fehler der regulären Abgabe keine direkten Rückschlüsse auf eine korrekte Lösung zulässt. Durch das Ausbessern dieser Fehler wird die Lösung nicht notwendigerweise richtig, sondern kann andere (nicht selten noch schwerwiegendere) Fehler enthalten. Versuchen Sie daher, die Gründe für Ihre Fehler und die richtige Lösung zu verstehen.

Schwerwiegendste Fehler:

Die Aufgabe ist so aufgebaut, dass die Untertypbeziehungen zwischen den geforderten Typen eindeutig sind. In etwa der Hälfte der Lösungen wurden diese jedoch nicht richtig erkannt. Außerdem wurden Teilaufgaben, die bei der Erkennung falscher Lösungen helfen sollten, häufig nicht gemacht und Empfehlungen in der Aufgabenstellung nicht beachtet. Folgende Klassen von Fehlern spielen eine große Rolle:
Untertypbeziehung angenommen, wo keine besteht:
Das ist der häufigste Grund für starke Punkteabzüge. Durch die genaue Beschreibung der geforderten Typen besteht wenig Spielraum beim Entwurf geeigneter Untertypbeziehungen. Trotzdem wurden alle möglichen Arten von Untertypbeziehungen angenommen, die nach dem Ersetzbarkeitsprinzip gar nicht existieren können. Die Methode toString ist hauptsächlich davon betroffen. Starke Punkteabzüge kommen vor allem daher, dass falsche Untertypbeziehungen ein wichtiger Grund für schwerwiegende Softwarefehler und nicht wartbaren Code in praktisch eingesetzten Systemen sind.
Keine Untertypbeziehung angenommen, wo eine bestehen könnte:
Das kommt nur selten vor, führt aber auch zu starken Punkteabzügen, da das Erkennen von Untertypbeziehungen der wichtigste Schwerpunkt dieser Aufgabe ist. Die Punkteabzüge sind weniger stark als im umgekehrten Fall, da solche Fehler zwar die Wartung erschweren, aber nicht zu falschem Verhalten der Software führen.
Keine, nicht hinreichende oder zu ungenaue Zusicherungen:
Untertypbeziehungen beruhen zum größten Teil auf Zusicherungen. Bei den meisten Lösungen waren die Zusicherungen in der einen oder anderen Form mangelhaft. Vor allem haben viele Gruppen die Nachbedingungen auf toString, auf die es in dieser Aufgabe hauptsächlich ankommt, nur halbherzig formuliert. Für mangelhafte Zusicherungen wurden nicht sehr viele, aber doch merklich Punkte abgezogen. Man muss aber annehmen, dass grobe Fehler in den Unterypbeziehungen häufig eine Ursache in mangelhaften Zusicherungen haben.
Fehlende oder unzureichende Tests der Ersetzbarkeit:
In sehr vielen Fällen wurde die Ersetzbarkeit gar nicht oder auf nur absolut unzureichende Weise getestet. Durch geeignete Tests hätten die gröbsten Fehler in den Untertypbeziehungen aufgedeckt werden können. In einigen Fällen haben Tests sogar Fehler aufgedeckt, aber die falschen Untertypbeziehungen wurden trotzdem nicht als solche erkannt. Für mangelhafte Tests wuden zwar häufig aber nur moderat Punkte abgezogen.
Fehlende Begründung für nicht vorhandene Untertypbeziehungen:
In der Aufgabenstellung waren Begründungen für nicht vorhandene Untertypbeziehungen durch Gegenbeispiele verlangt. Dieser Teil wurde am häufigsten ignoriert, obwohl entsprechende Überlegungen fast automatisch zu einer richtigen Typhierarchie geführt hätten.
Kopieren einer Standardlösung:
Anscheinend hat sich ein großer Teil der Teilnehmer nicht auf die eigenen Fähigkeiten verlassen, sondern die eigenen Lösungen auf einem von anderen entwickelten Grundgerüst aufgebaut. Häufig führt dies jedoch zu einer ganzen Reihe kleiner Unstimmigkeiten und Fehler, die daher rühren, dass das Grundgerüst nicht gut mit anderen Teilen harmoniert. Beispielsweise passen Typhierarchien und Zusicherungen nicht zusammen, oder mangels Mitwirkung bei der Entwicklung der Typhierarchien fehlen brauchbare Ideen für das Testen der Untertypbeziehungen und für die Begründung nicht vorhandener Untertypbeziehungen. Solche Unstimmigkeiten führen nicht selten zu kleineren Punkteabzügen in der vorläufigen Beurteilung. Vor allem entsteht durch das Kopieren (wesentlicher Teile) der Lösung jedoch die Gefahr einer negativen Beurteilung des gesamten Laborübungsteils oder zumindest eines gravierenden Punkteverlusts beim Abgabegespräch.

Ersetzbarkeit:

Folgende Hinweise beziehen sich nur auf einige wenige Beziehungen zwischen den in dieser Aufgabe vorgegebenen Typen, die exemplarisch dargestellt werden. Es werden nicht alle denkbaren Beziehungen angesprochen.
Ist ScrollBlock Untertyp von WindowBlock?
Um diese Frage zu beantworten, brauchen wir nur die beiden Beschreibungen (genauer: die Zusicherungen) der Typen gegenüberstellen. Die Antwort ist Ja, wenn die Nachbedingungen und Invarianten in ScrollBlock jenen in WindowBlock entsprechen, aber möglicherweise genauer sind (also auf mehr Details eingehen), und die Vorbedingungen in WindowBlock jenen von ScrollBlock entsprechen, aber möglicherweise genauer sind.

Wir betrachten (vereinfachte und unvollständige) Nachbedingungen auf toString: In einer Instanz von ScrollBlock gibt toString einen Block aus, der einen beliebig wählbaren Ausschnitt aus einem längeren Text darstellt, während toString in einer Instanz von WindowBlock immer einen Block ausgibt, an dessen linker oberer Ecke der darzustellende Text beginnt. Alleine daraus können wir schon folgern, dass ScrollBlock kein Untertyp von WindowBlock sein kann: Sobald der linke oder obere Rand in einer Instanz von ScrollBlock auf einen anderen Wert als Null gesetzt wurde, muss ein Aufruf von toString etwas anderes zurückgeben, als ein Aufruf von toString in einer Instanz von WindowBlock zurückgeben würde. Aufgrund dieses Gegenbeispiels ist die Ersetzbarkeit nicht mehr gegeben. Umgekehrt kann WindowBlock auch kein Untertyp von ScrollBlock sein, da es in WindowBlock (wegen der Zusicherungen auf toString) keine Möglichkeit geben kann, den Rand des auszugebenden Textes zu ändern, genau diese Möglichkeit von ScrollBlock aber verlangt wird.

Ein wichtiger Grund für die fehlende Untertypbeziehung zwischen ScrollBlock und WindowBlock ist folgender: Das Verhalten von toString ist in beiden Klassen so genau festgelegt, dass man eine Beschreibung (= Nachbedingung) nicht mehr als allgemeinere Variante der anderen ansehen kann. Man könnte die Beschreibung in WindowBlock verallgemeinern, indem man weniger Details festlegt, und dadurch ScrollBlock zu einem Untertyp von WindowBlock werden lässt. Diese verallgemeinerte Beschreibung würde jedoch nicht der Aufgabenstellung entsprechen und daher als falsch beurteilt werden. Aber in einer abstrakten gemeinsamen Oberklasse von ScrollBlock und WindowBlock kann man die Beschreibung durchaus auf diese Weise verallgemeinern ohne eine Bedingung in der Aufgabenstellung zu verletzen.

Ist TextBlock Untertyp von FillBlock?
Diese Untertypbeziehung ist tatsächlich gegeben: Eine Instanz von TextBlock entspricht einer Instanz von FillBlock, wobei das Leerzeichen als Füllzeichen verwendet wird. Dadurch entsprechen einander auch die Zusicherungen aller Instanzmethoden der beiden Klassen, wenn das Füllzeichen entsprechend gesetzt ist. In der Nachbedingung von toString in TextBlock braucht (im Vergleich zu der in FillBlock) nur Füllzeichen durch Leerzeichen ersetzt werden. Die Nachbedingung in TextBlock ist stärker als die in FillBlock da ein ganz bestimmtes Füllzeichen verlangt wird. Umgekehrt kann FillBlock deswegen kein Untertyp von TextBlock sein; die Nachbedingung im Untertyp darf ja nicht schwächer sein als im Obertyp.

Fehlerursachen:

Die tatsächlichen Ursachen für die schwerwiegendsten Fehler können nur vermutet werden. Folgendes spielt aber sicherlich eine Rolle:
Verwechslung von Untertyp- mit is-a-Beziehungen:
Viele Teilnehmer haben den Umgang mit is-a-Beziehungen schon in anderen Lehrveranstaltungen gelernt. Solche aus der realen Welt abgeleiteten Beziehungen sind vor allem in einer frühen Designphase wichtig, um Softwareeinheiten in Relation zueinander zu setzen und dadurch zu brauchbaren Faktorisierungen zu kommen. Häufig lassen sich is-a-Beziehungen zu Untertypbeziehungen weiterentwickeln, aber nicht immer. Diese Aufgabe wurde absichtlich so gewählt, dass is-a-Beziehungen kaum zu Untertypbeziehungen weiterentwickelt werden können, damit Verwechslungen zwischen diesen Beziehungen möglichst ausgeschlossen werden. Es geht in dieser Aufgabe nicht darum, intuitiv abzuschätzen, ob und wie je zwei Typen zueinander in Beziehung stehen könnten (das wäre eine is-a-Beziehung), sondern ausschließlich darum, ob die Beschreibung eines Typs auch der Beschreibung eines anderen Typs (für alle möglichen Verwendungsfälle) entspricht. Wer das Gefühl hat, dass die Aufgabe je nach Sichtweise verschiedene Lösungen haben kann, hat diese beiden Arten von Beziehungen mit großer Wahrscheinlichkeit miteinander verwechselt. Untertypbeziehungen sind (bei ausreichend klar formulierten Zusicherungen) im Gegensatz zu is-a-Beziehungen immer eindeutig.
Verwechslung von Untertyp- mit Vererbungs-Beziehungen:
Einige Teilnehmer haben Untertypbeziehungen offensichtlich mit Vererbungsbeziehungen verwechselt, vielleicht weil sie mit Vererbung vertraut sind, aber noch keine Erfahrungen mit Untertypbeziehungen haben. Die einfachste Form der direkten Code-Wiederverwendung ergibt sich durch eine Klassenhierarchie, die durch die Reihenfolge der Beschreibungen der Klassen in der Aufgabenstellung vorgegeben scheint. Vielleicht haben sich einige Teilnehmer davon verwirren lassen, dass die scheinbar vorgegebene Reihenfolge, die intuitive is-a-Beziehung und die einfachste Vererbungshierarchie eine einheitliche Struktur ergeben. Diese Hierarchie hat aber leider gar nichts mit Untertypbeziehungen zu tun und widerspricht dem Ersetzbarkeitsprinzip.
Verlassen auf Erfahrung und Intuition statt auf konkrete Grundlagen:
Bei dieser Aufgabe haben auch einige Gruppen, deren Mitglieder schon viel Programmiererfahrung haben, versagt. Ein Mitgrund dürfte darin liegen, dass diese Gruppen die Aufgaben eher nach Intuition lösen, als auf den in den Vorlesungen und im Skriptum behandelten Stoff einzugehen. Eine typische Folge davon ist beispielsweise die Verwechslung verschiedener Arten von Beziehungen zwischen Klassen. Alle zur Lösung dieser Aufgabe notwendigen Grundlagen wurden in den Vorlesungen ausführlich behandelt. Es fehlt aber gelegentlich der Mut, den neu erlernten Stoff auch in die Praxis umzusetzen, und es erscheint fälschlicherweise sicherer, sich auf (unzureichende) eigene Erfahrungen und Intuitionen zu verlassen, als sich auf ein unbekanntes Gebiet zu begeben. Jetzt ist der Punkt gekommen, wo Vorwissen alleine oft nicht mehr ausreicht, um die Aufgaben gut zu lösen. In einigen Fällen haben Testergebnisse sogar klare Verletzungen der Ersetzbarkeit gezeigt - ein deutlicher Hinweis darauf, dass der Begriff der Ersetzbarkeit noch nicht verstanden wurde.
Zu wenig Selbstvertrauen:
Bei einigen Gruppen dürfte mangelndes Selbstvertrauen eine Rolle gespielt haben: Durch zuviel Respekt vor der Aufgabe haben es manche nicht gewagt, selbst entwickelte Klassenhierarchien auszuprogrammieren und Zusicherungen in eigenen Worten zu formulieren. Sicher haben sich viele eher auf irgendwelche in Forumsdiskussionen oder sonst irgendwo im Internet angebotene Informationen als auf das eigene Wissen verlassen. Ganz allgemein sind Diskussionen in Foren durchaus zu begrüßen. Gefährlich wird es aber, wenn man das Gefühl bekommt, dass Lösungen und Argumente von vielen anderen Leuten besser sind als die eigenen (= mangelndes Selbstvertrauen) und daher nur mehr vorgefertigte Lösungen oder Lösungsansätze übernimmt. Damit begibt man sich ganz in Abhängigkeit von Leuten mit mehr Selbstvertrauen (die aber deswegen nicht unbedingt immer bessere Lösungen haben) und kann bzw. möchte bald auch einfachste Aufgaben nicht mehr selbst und ohne Rückbestätigung lösen. Eine fremde Lösung schaut oft nur deswegen besser aus als die eigene, weil man Probleme, die während der Entwicklung der Lösung aufgetaucht sind, nicht mehr sieht, während Probleme der eigenen Lösung ganz offensichtlich sind. Daher ist es ein großes Risiko, sich ganz auf andere (einem oft unbekannte) Leute zu verlassen. Es ist auch deswegen ein Risiko, weil Lösungen, die man nicht selbst gemacht sondern nur abgeschrieben hat und daher beim Abgabegespräch nicht im Detail erklären kann, mit 0 Punkten beurteilt werden (auch wenn man in der vorläufigen Beurteilung viele Punkte bekommen hat). In der Regel fällt es auf, wenn große Teile der Lösung abgeschrieben sind. Beispielsweise passt die Struktur einer Lösung einfach nicht zur Namensgebung oder zu den Kommentaren. Zusammengefasst gilt: Es ist durchaus gerechtfertigt, in Foren Probleme zu diskutieren und auch Lösungsansätze anzubieten oder danach zu fragen. Wissen, das man dabei gewinnt, kann und soll man in die eigenen Lösungen einfließen lassen. Aber man soll sich keinesfalls nur auf andere verlassen, sondern alle gewonnenen Informationen hinterfragen und nur dann verwenden, wenn man sie auch im Detail versteht und die Strukturen, die man übernehmen möchte, auch tatsächlich zur eigenen Lösung passen. Meist funktioniert es nicht, wenn unpassende Strukturen erst passend gemacht werden müssen.
Teilaufgaben und Hinweise ignoriert:
Teile der Aufgabenstellung hatten nur den Zweck, Fehler in der Lösung möglichst rasch aufzudecken. Außerdem wurden Hinweise dazu gegeben, wie die Korrektheit der Lösung sichergestellt werden kann. Viele Gruppen haben die entsprechenden Teile der Aufgabe und die Hinweise einfach ignoriert. Beispielsweise wurde die Ersetzbarkeit kaum getestet, Gegenbeispiele für nicht bestehende Untertypbeziehungen wurden nur selten gegeben, und oft wurden aus einer Oberklasse übernommene Zusicherungen in der Unterklasse nicht wiederholt. Gerade Letzteres hätte viele falsche Untertypbeziehungen rasch auffallen lassen müssen. Das ist beispielsweise auch daran gescheitert, dass viele gar nicht auf die Idee gekommen sind, in einer Unterklasse auch für ererbte Methoden (die deswegen in der Unterklasse nicht implementiert sind) Zusicherungen zu schreiben.

Beurteilungsschema

Für ein abgegebenes Programm, das sich übersetzen lässt, gibt es 100 Punkte. Davon werden für Fehler im Programm Punkte abgezogen. Generell gibt es mehrere Klassen von Fehlern mit je einer eigenen maximalen Anzahl von abgezogenen Punkten: Einige Fehlerklassen stehen in enger Beziehung zueinander. Diese werden in der Beurteilung berücksichtigt. Wenn beispielsweise Punkte für falsche Untertypbeziehungen abgezogen wurden, dann wurden für mangelhafte Zusicherungen nur mehr weniger Punkte abgezogen, wenn angenommen werden kann, dass die Mängel in den Zusicherungen eine Mitursache für falsche Untertypbeziehungen sind. Meist steht in diesen Fällen das Wort Folgefehler bei dem Kommentar, der ohne weitere Fehler zu höheren Punkteabzügen geführt hätte; dieser Zusatz erlaubt aber keine Rückschlüsse darauf, welcher Fehler aus welchem anderen Fehler folgt.
Complang
Puntigam
   Kontakt
   Research
   Lehre
      OOP
      Typsysteme
      EP2
      FOOP
      Prog.spr.
      frühere Lehre
         LVAs 2017 W
         LVAs 2017 S
         LVAs 2016 W
         LVAs 2016 S
         LVAs 2015 W
         LVAs 2015 S
         LVAs 2014 W
         LVAs 2014 S
         LVAs 2013 W
         LVAs 2013 S
         LVAs 2012 W
         LVAs 2012 S
         LVAs 2011 W
         LVAs 2011 S
         LVAs 2010 W
         LVAs 2010 S
         LVAs 2009 W
            OOP
               1. Aufgabe
               2. Aufgabe
               3. Aufgabe
               4. Aufgabe
                  Beurteilung
               5. Aufgabe
               6. Aufgabe
               7. Aufgabe
               8. Aufgabe
               9. Aufgabe
               Cacao
            Typsysteme
         LVAs 2009 S
         LVAs 2008 W
         LVAs 2008 S
         LVAs 2007 W
         LVAs 2007 S
         LVAs 2006 W
         LVAs 2006 S
         LVAs 2005 W
         LVAs 2005 S
         LVAs 2004 W
         LVAs 2004 S
         LVAs 2003 W
   Links
Sitemap
Kontakt
Fakultät für Informatik
Technische Universität Wien
Anfang | HTML 4.01 | Datenschutzerklärung | letzte Änderung: 2009-11-16 (Puntigam)