Es war einmal ein König, der hatte drei Kinder und ein kleines, einstmals schönes Schloss. Das Schloss war alt und heruntergekommen und es war dort kalt und feucht. Der König aber war alt und Waise. Weil sich nun der Erzähler bei diesem Satz vertippt hatte, das aber nicht zugeben wollte, bedeutete das, dass der besagte Monarch keine Eltern mehr hatte. Also dachte der graue König bei sich:

„Ich bin alt und hier ziehts wie Hechtsuppe. Wenn ich nicht will, dass auch meine Kinder bald zu Waisen werden, muss sich da was ändern!“

Da der König aber sehr beschäftigt war, rief er Alice, seine älteste Tochter zu sich und sagte:

„Alice, ich bin alt und hier ziehts wie Hechtsuppe. Mach dass das besser wird. Hier hast du fünf Goldmünzen.“ (mehr …)

Vor einiger Zeit hat man mir mal gesagt, wenn es um Aufwandsschätzungen geht, schätze ich „konservativ“. Will heißen: Ich schätze übervorsichtig, also zu hoch. Ob das stimmt? Ich weiß es nicht. Ich hab die Kritik also erstmal angenommen und zum Anlass genommen, darüber mal genauer nachzudenken. Zumal ich mir das bei mir gut vorstellen kann. Darüber hinaus gab es in letzter Zeit noch ein paar andere Begebenheiten, die mich dazu bringen, mir mal Gedanken übers Schätzen zu machen. Das Nachdenken hat ne Zeit lang gedauert. Der Text liegt hier also schon ein paar Monate rum. Dafür ist er aber auch umso ausführlicher geworden.

Warum schätzen wir daneben?

Selbst unter perfekten Bedingungen werden wir niemals in der Lage sein, immer perfekte Voraussagen zu machen. Mal werden wir zu hoch schätzen und mal zu niedrig. Wir können annehmen, dass eine Schätzung normalverteilt ist. Je besser wir schätzen, desto enger, gestauchter wird die Kurve (niedrige Standardabweichung), je schlechter wir schätzen, desto breiter und gestreckter wird sie (hohe Standardabweichung). Neben der generellen Ungenauigkeit beim Schätzen kann es natürlich noch ein Bias geben: Ein Schätzer kann die Tendenz haben, zu hoch oder zu niedrig zu schätzen. Das kann ein psychologischer Effekt oder ein systematischer Fehler sein.

normal_distributions

Das nächste Problem ist, dass das mit der Normalverteilung an sich schon gelogen ist. Typischerweise gibt es mehr Möglichkeiten, dass etwas schief gehen kann, als Möglichkeiten, dass alles perfekt klappt. Oder anders gesagt: Es kann immer noch katastrophaler werden, aber besser als in Windeseile bugfrei fertig sein ist nunmal nicht möglich. Eine gewisse Zeit braucht man auch zum einfach so runtercoden. Pessimistische Schätzungen sind demnach wahrscheinlicher als optimistische. Tom DeMarco veranschlagt deshalb für Aufwandsschätzungen eine asymmetrische Verteilung:

Achtung: Auch, wenn die beiden Grafiken ähnlich aussehen, haben sie doch eine leicht andere Semantik: Die erste Grafik verdeutlicht die Wahrscheinlichkeitsverteilung einer Schätzung um einen unbekannten, aber festen Aufwandswert. Diese Grafik hier zeigt die Verteilung des tatsächlichen Aufwands selbst. Das nur der Vollständigkeit halber. Für die weitere Betrachtung spielen diese Details keine Rolle.

Weitere Fehler treten dadurch auf, dass manche Aufgaben und Anforderungen gar nicht geschätzt bzw. nicht berücksichtigt werden.

Unsere Probleme beim Schätzen sind also die folgenden: (mehr …)

Hänsel und Gretel haben ein spontanes Meeting im Wald. Äh… das heißt… sie haben sich verirrt. Diese Tatsache ist nicht weg zu diskutieren. Hier ist Wald, dort ist Wald. Hier ist der Wald dunkler als dort. Hier geht es bergauf, dort bergab. Hier ist es neblig, dort gibt es Dornenhecken. Überall ist es ein bisschen anders ungemütlich. Aber eins ist klar: Hier sollten die beiden nicht sein; wo auch immer „hier“ genau ist. Und deshalb haben sie beschlossen, spontan ein Meeting abzuhalten und über ihre Situation zu diskutieren.

Hänsel_und_Gretel

Man kann nun unterschiedliche Gründe suchen, wie die beiden in diese Lage gekommen sind. Die naheliegendste Ursache ist wohl die Stiefmutter. Es war ja schließlich ihre Idee, die Kinder in den Wald zu schicken. Und jeder weiß, dass Stiefmütter böse sind, also muss sie einfach schuld sein.

Vielleicht steckt da aber auch mehr dahinter. (mehr …)

Ich weiß schon, warum ich Entwickler geworden bin. Im Studium hatte ich eine Vorlesung zu „Unternehmensführung“. Strategie, Organisation, Controlling, Personalwirtschaft, internationales Management… alles das hat man mir beigebracht. In der Klausur hab ich sogar ne ganz gute Note gekriegt, wenn ich mich richtig erinnere. Aber wäre ich dadurch ein guter Chef? Ich weiß schon, warum ich Entwickler geworden bin — und warum ich wahrscheinlich niemals ins Management wechseln werde.

Eins ist natürlich klar: Management kann manchmal echt verwirrend sein und zu Missverständnissen führen. Aber was macht eigentlich ein Chef? Fragt man in der Fußgängerzone, wird man vermutlich sowas hören wie „entscheiden und delegieren“. Ein Chef entscheidet, was gemacht wird und weist dann seine Untergebenen an, die dafür notwendige Arbeit zu tun. Dieses Führungsmodell stammt aus dem Militär und der Industrie — und es funktioniert in der Softwareentwicklung nicht. In „Leadership in der IT“ zeigt Johann-Peter Hartmann anschaulich wie sich Führungsstile über die Zeit entwickelt haben und warum man Produktionsstätten nicht mit Softwareentwicklung vergleichen kann. In Handwerksbetrieben ist die Aufgabe des Meisters gegenüber seinen Gesellen und Lehrlingen das Anleiten und nach Außen hin vertreten. In der Industrie ist es, wie gesagt, das Entscheiden und Delegieren. Mittlerweile schon weit verbreitet ist die Auffassung, Chefs sollten Ziele definieren und Feedback geben. Moderner wäre zu sagen, sie motivieren und etablieren Wertesysteme.

Ich behaupte jetzt aber mal folgendes: Ein Chef hat genau zwei Aufgaben: gärtnern und vorgaukeln. Aber ich glaub, das muss ich erklären… (mehr …)

Von manchen Dingen gibt es einfach nur endlich viele. Von Pronomen beispielsweise. Ich, du, er, sie, es, wir, ihr, sie. Das sind die Personalpronomen. Gut, man kann diese noch deklinieren, aber dann ist auch schon Schluss. Niemand würde auf die Idee kommen, ein neues Personalpronomen zu erfinden. Es gibt einfach nur endlich viele davon. Keine Chance, das zu ändern. Anders ist es beispielsweise mit Verben. Davon entstehen ständig neue. „Simsen“, „googlen“, „chillen“, „refactoren“… Es gibt immer wieder Neologismen. Niemand würde auf die Idee kommen, zu behaupten, man hätte bereits alle Verben erfunden. Man sagt, Pronomen sind eine „Closed Word Class“ und Verben sind „Open Word Class“ [1]. Die Unterscheidung braucht man mitunter, um zu bestimmen, welche Wörter man in englischen Überschriften groß schreibt.

Jetzt kommt das Interessante: Dass Pronomen endlich sind und Verben nicht, ist für uns zwar einigermaßen klar und intuitiv, aber es kann auch anders sein. Ich kann zwar kein Japanisch, aber zumindest laut Wikipedia ist es dort genau umgekehrt. Dort gibt es nur endlich viele Verben, aber potenziell unendlich viele Pronomen. Beide Varianten funktionieren also offensichtlich. Zumindest gehe ich davon aus, dass sich Japaner untereinander verstehen.

Wenn ich Japanisch lernen wollte, so müsste ich also erst einmal die Denkweise der japanischen Grammatik lernen. Die romanischen und germanischen Sprachen, die wir so typischerweise kennen, funktionieren alle ähnlich. Egal ob Deutsch, Englisch, Französisch oder Italienisch: Die Vokabeln unterscheiden sich und auch die Grammatik ist anders, aber die grundlegende Denkweise: grammatische Formen, Kasus, Zeiten, Pronomen, Deklination und Konjugation… Die grundlegenden Konstruktionsbausteine der Sprachen sind sehr ähnlich. Das ist aber keine Selbstverständlichkeit. Andere Sprachen können durchaus auch anders funktionieren. Und beim Japanischen und vermutlich noch vielen anderen (asiatischen, etc.) Sprachen ist das wohl so. Unser Wissen, wie man Verben konjugiert, hilft beim Lernen von Japanisch nicht. Im Französischen konjugiert man anders als im italienischen. Aber trotzdem sind Verben immer noch von Numerus und Person abhängig. Japanisch ist hier ganz anders.

Ähnliche Effekte lassen sich auch in der Softwareentwicklung beobachten. Sprachen wie Java, C++ oder Delphi haben im Detail große Unterschiede. Aber Konzepte sind ähnlich. Und es gibt Sprachen, die vollkommen anders sind. In Haskell beispielsweise gibt es noch nichtmal Variablen.

Aber die Analogie lässt sich noch weiter treiben: Auch in Programmiersprachen und Technologien gibt es endliche und erweiterbare Strukturen — Closed Classes und Open Classes. Typische Programmiersprachen, Technologien und Architekturen gehen einen ähnlichen Weg wie das Englische (und diverse andere, wenn nicht sogar alle europäische Sprachen): Es gibt potenziell unbegrenzt viele Verben bzw. Methoden. Aber muss das so sein? Könnte man nicht… so wie im Japanischen? Kann man. Und das tut REST. Dort gibt es auch nur endlich viele Verben. Aber gucken wir uns das einmal genauer an… (mehr …)

In den letzten Jahren ist REST zu einer beliebten Schnittstellentechnologie geworden. Das hat mehrere Gründe und einer davon ist, dass REST als einfache Technologie verstanden wird. Und das ist auch richtig. Gewissermaßen. Irgendwie. Fakt ist aber auch, dass man REST erstmal lernen und verstehen muss. Bei REST gerät man leicht in Versuchung zu meinen, etwas verstanden zu haben, obwohl das nur bedingt der Fall ist. REST wirkt erstmal einfach, aber REST ist vor allem auch anders. Es liegt eine andere Denkweise zugrunde. Ich haben schon mehrere REST-Services geschrieben und ebenso auch mehrere benutzt. Nun mache ich das seit Monaten und trotzdem komme ich immer wieder in die Situation, dass ich merke, dass ich etwas falsch oder zumindest nicht ganz vollständig verstanden habe.

Einführungen in REST gibt es wie Sand am Meer. Wenn man sich davon mal ein paar angesehen hat, wird man feststellen, dass es davon eine Handvoll Arten gibt. Unterschiedliche Herangehensweisen, unterschiedliche Schwerpunkte und unterschiedliche Nützlichkeit. Folgende Arten hab ich finden können: (mehr …)

Irgendwie komme ich kaum zu posten. Unter anderen wartet ein Artikel zu REST (wobei das vermutlich mehrere werden) in der Pipeline. Jetzt sind aber erstmal die Delphi-Tage dran. Und bevor sich das hier gar nicht mehr mache, kurz und bündig:

  • Die diesjährigen Delphi-Tage in Bonn haben mir wieder gut gefallen.
  • Mit Delphi hab ich mittlerweile eigentlich kaum noch etwas zu tun. Aber es war 10-jähriges Jubiläum der Delphi-Tage und ich hab Martin ein wenig vertreten dürfen. Es waren meine siebten Delphi-Tage und vielleicht meine letzten. Aber man soll ja nie nie sagen…
  • Die Begrüßung verlief ungeplanterweise etwas improvisierter als von mir angedacht. Aber ich denke, es haben sich trotzdem alle begrüßt gefühlt.
  • Mein Vortrag war insgesamt ganz gut besucht und ich bin im Großen und Ganzen auch zufrieden. Das ein oder andere hätte ich besser machen können, aber ich fands in Ordnung.
  • Ich hab vermutlich etwas zu oft Fragen ins Publikum gegeben. Ich sollte lernen, das gezielter einzusetzen.
  • Vermutlich hat man gemerkt, dass ich deutlich weniger Zeit in Folien und Vortragsvorbereitung gesteckt habe, als in den letzten Jahren. Die Folien waren sehr codelastig und an der ein oder anderen Stelle gabs kleine Fehler. Und er Vortrag lief nicht überall ganz rund: „Hab ich hierzu ne Folie? Äh ne hab ich nicht“.
  • Danke an die aufmerksamen Zuhörer, die mich auf das ein oder andere Problem hingewiesen haben. Ich soweit ich mich daran erinnern konnte, hab ich die Folien entsprechend korrigiert.
  • Ich hab das Gefühl, mein Problem mit dem „äh“ ist besser geworden. Ob dem so ist?
  • Die Beispiele kamen, nach dem, was ich so gehört habe, nicht ganz so gut rüber, wie erhofft. Ich von meiner Seite aus, war mit ihnen eigentlich sogar recht zufrieden. Trotz der kurzen Vorbereitungszeit hab ich nur an einer Stelle auf ein Foobar-Beispiel ausweichen müssen (Dafür war das auch besonders schlecht 😉 ). Woran die anderen Beispiele gekrankt haben, weiß ich noch nicht so genau.
  • Feedback ist wie immer jederzeit herzlich willkommen.

Das mit dem Testen ist eine merkwürdige Sache. Meine Beobachtungen zu dem Thema sehen in Etwa folgendermaßen aus:

  • Testen die ungeliebte Tätigkeit. Häufig ist das Testen eine ungeliebte Tätigkeit. Sie wird als langweilig, eintönig und unproduktiv empfunden. Viele schreiben lieber Produktivcode als Testcode. Als ich in der Uni das Softwareentwicklungsprojekt betreut hatte, musst ich meine Studenten fast schon dazu zwingen, JUnit-tests zu schreiben (und das war explizit Teil der Aufgabenstellung). Die besten Gruppen hatten eine gefühlte Testabdeckung knapp über „kaum nennenswert“.
  • Testen an der Uni. An der Uni wird auch das Testen thematisiert. Aber wie… Was lernt man da? Hauptsächlich Begriffe. Blackbox, Whitebox, Testtreiber, Dummy, Unittests, Integrationstest, … Man lernt einzelne Details über Testabdeckung, Path Coverage, Statement Coverage, Branch Coverade, MCDC Coverage, … Man lernt was über statistische Testverfahren, Äquivalenzklassen und Grenzwertanalyse. Was aber lernt man nicht? Testen. Aber Zeug wie Mocking-Frameworks und TDD wurden gar nicht behandelt. Und was schon gar nicht Teil des Studium war, ist explizit mal zu lernen, wie man Code testbar macht. Testen muss man lernen wie ein Handwerk. Und wenn man mal ein gewissen Gefühl dafür bekommen hat, verliert es auch ganz schnell seinen Schrecken. Denn Testen ist eigentlich alles andere als langweilig und unproduktiv.
  • Testen als Spezialqualifikation. Es gibt die einen Tests, die man selbst schreibt. Manchmal hat man aber auch den Luxus separate Tester zu haben. Das sind Leute, die die abartigsten Fehlerfälle finden und ein Gespür dafür haben, was noch alles schiefgehen könnte. Wenn man so jemanden hat, ist das ein echter Mehrwert. Automatisierte Unit-Tests sind zwar immer noch unersetzbar, aber durchaus sinnvoll ergänzbar.
  • Testen und Dokumentation. Wasserfall-Tester müssen Berge von Doku schreiben. Das ist auch das, was man so in der Uni gelehrt bekommt. Testkonzepte, Statusreports, Testspezifikationen, Testergebnisse… Alles wird dokumentiert. Das passt schön in die Wasserfall-Denkweise und mag in Fällen, in denen es um sicherheitskritische Software (Autos, Flugzeuge, Computertomographen, …) geht, aus rechtlichen Gründen angebracht sein. Allerdings frag ich mich manchmal: Welchen zusätzlichen Mehrwert könnten unsere Tester liefern, wenn sie nicht die Hälfte ihrer Zeit mit Papierkram verplempern würden?
  • Tests haben. Einer meiner Profs stellte immer den wissenschaftlich nachgewiesenen Effektivitätsvorteil von Inspektionen gegenüber Tests heraus. Was aber meist untern Tisch fällt, ist die Feststellung, dass das Punkt bei automatisierten Tests ein ganz anderer ist. Es kommt nicht darauf an, Tests zu schreiben. Das Tolle ist, sie zu haben. Wenn man sie einmal geschrieben hat, kann man sie regelmäßig fast ohne Aufwand neu ausführen. Und das ist wirklich ein *riesiger* Vorteil. Man kann so viel entspannter refactorn. Bestehende Funktionalität geht nicht so einfach kaputt, weil man Tests hat, die das prüfen. Nötige Verbesserungen werden nicht aus Angst, etwas kaputt zu machen, verschlafen… Viele Effekte, die ungemein positiv für die Qualität sind.
  • Testen als Handwerk. Wie gesagt: Testen ist ein Handwerk, das man erlernen muss. Eines, das man in der Uni nicht lernt. Auch, wenn ich schon seit über zwölf Jahren programmiere, richtig testen hab ich erst in den letzten Monaten gelernt. Und ich hab das Gefühl, dass ich noch mehr zu lernen habe und noch mehr lernen werde.

Letztens hab ich zwei Artikel gelesen, die meinem Verständnis für Tests wieder einen Schub nach vorne verpasst haben. Und das sind die beiden:

Da steht viel Interessantes drin, aber ich will mal eines hervorheben, was ich besonders wichtig finde: Einer der Fehler bzw. ein Missverständnis, dem auch ich aufgesessen bin, ist dass es zu jeder Klasse eine Test-Klasse geben müsse. Ich hab sogar mal nen Test geschrieben, der geprüft hat, ob zu jeder Klasse ne Testklasse und zu jeder Methode ne Testmethode existiert. Und das ist Blödsinn. Der Effekt der dann auftritt, ist, dass jegliches Refactoring ein analoges Refactoring der Tests nach sich zieht. Benenne ich eine Methode um, muss ich auch alle zugehörigen Testmethoden umbenennen. Teile ich eine Klasse, muss ich auch den eine neue Testklasse schreiben, etc. Das ist ein Hemmschuh, der eigentlich nicht da sein sollte. Vielmehr sollten Tests orthogonal zum Produktivcode sein. Tests sollten sich an der Fachlichkeit orientieren, nicht an der technischen Struktur des realisierenden Codes. Es gibt also quasi pro fachlicher Anforderung eine Testklasse.

Ich hab das mal bei meinem ArgumentsParser ausprobiert und das ist tatsächlich ein enormer Fortschritt.

Drei Monate nach meinem letzten Post zu Clean Code hier nun wieder einer. Und wieder grab ich in den Krümeln und tu so als könnt ich alles besser. Heute behaupte ich mal, ich könnte einen besseren Parser für Kommandozeilenargumente schreiben.

In Kapitel 14 „Successive Refinement“ zeigt Bob Martin sehr detailliert (auf über 50 Seiten) wie man Code schrittweise refactort. Das Kapitel ist wirklich, wirklich lesenswert, weil es die einzelnen Schritte beschreibt und zeigt, wie sich der Code verändert. Das Schwere oder eher: das, was man beim Refactoring nämlich üben muss, ist, wie man alles so kleinschrittig macht, dass die Tests immer durchlaufen. Schnell passiert es, dass man sein System an diversen Stellen ändert und es dann erstmal für Stunden nicht funktioniert, vielleicht nichtmal durch den Compiler geht. Die Kunst ist es nun, die Schritte so zu wählen, dass eben genau das nicht passiert. Mir passiert es immer noch, dass ich Code kaputtändere und ihn dann erst wieder zusammenflicken muss. Dieses Kapitel hat mir geholfen, dass das nun seltener passiert, wenngleich noch ein wenig mehr üben muss.

Aber ich wollte ja mal wieder ein wenig besserwisserisch auftreten und an Uncle Bobs Code rumkritteln. Wenngleich ich bewundere, wie der Mann refactort; das Endergebnis gefällt mir nicht so. Gucken wir uns erstmal an, wie seine Musterlösung denn aussieht: (mehr …)

Remember remember the fifth of November… I certainly do remember the fifth of November—which was last Tuesday. I don’t remember it because of the Gunpowder Plot, certainly not because of the nursery rhyme and at least not today because of V for Vendetta. Rather I once more gave my talk on principle languages. This time as a webcast to Sydney, Australia.

This is also a premiere. This is not the first time for me to present the topic. Neither it is my first webcast or my first presentation in English. But this time I have a recording. And here it is: (mehr …)