TDD 2.0 – Teil 2 | TDD as if you meant it (TDDaiymi)

“TDD ist kein Zauberstab, der aus dem Nichts wohlstrukturierten Code herstellt.” – Ralf Westphal [1]

TDD 2.0 – Teil 1 | Problemanalyse, Lösungsfindung, Implementierung

Die Refactoring-Phase in TDD dient dazu Code zu strukturieren. Es gibt allerdings keine generellen Rezepte nach welchen Kriterien man verbessertes Design als Entwickler erzeugen kann. Code Smells, wie z.B.: Duplikation, sind zwar gute Ansatzpunkte, allerdings führt die Bereinigungen dieser in TDD 1.0 nicht automatisch zu guter Struktur (= Aspekte meiner Lösung für das vorhandene Problem werden durch Refactoring nicht automatisch im Code abgebildet).

Ralf Westphal beschreibt in einer vierteiligen dotnetpro-Artikelserie, wie seiner Meinung nach das neue TDD, also TDD 2.0,auszusehen hat. Den ersten Teil habe ich bereits hier zusammengefasst. Darin ging es um die ersten beiden (neuen) Phasen: Problemanalyse und Lösungsfindung.

In diesem Post fasse ich den zweiten Teil [1] der Artikelserie von Ralf zusammen: die Implementierungsphase. Ralfs Kritik von TDD 1.0 ist das Refaktorisieren, das nicht durch die Methode selbst erzwungen wird. Dadurch wird diese Phase willkürlich von Entwicklern eingesetzt bzw. es wird komplett darauf verzichtet. Struktur kann, muss allerdings nicht, dabei entstehen. Genau das ändert sich bei TDD 2.0 in der Implementierungsphase durch den Einsatz von TDD as if you meant it.

Die Regeln von TDDaiymi sind einfach: Produktionscode wird immer nur in die Test-methode geschrieben. Fehler müssen zuerst in der Testmethode reproduziert und behoben werden. Dann wird in den Testmethoden nach Wiederholungsmustern gesucht, die Anzeichen zur Refaktorisierung darstellen.

Produktionscode nur in Testmethoden? Ja. Laut Ralf treten dabei folgende Effekte auf:

“Erstens konzentriere ich mich bei jedem Testfall nur darauf, genau diesen Testfall grün zu bekommen. Die Fokussierung ist viel größer. Ich muss keine Kompromisse bei der Lösung eingehen. Das bedeutet auch, ich bewege mich tastend fort. … Und zweitens entstehen viel häufiger (Wiederholungs-)Muster. Die sind Leitsterne für die Refaktorisierung.” [1]

Keine Kompromisse?

Da man bei TDDaiymi die Behebung eines Fehlers immer in der Testmethode selbst programmiert, läuft man nicht Gefahr,  andere Tests kaputt zu machen. Das sieht bei TDD 1.0 anders aus. Die Regeln besagen: Bereits erzeugte Tests, die einmal auf Grün waren, dürfen nicht mehr Rot werden. Deshalb muss man sich bei jedem neuen Test plus Implementierung darauf konzentrieren, dass die neue Lösung ebenfalls alte Tests berücksichtigt und nicht zerstört. Das ist in TDD 2.0 nicht mehr der Fall, denn Tests plus deren Implementierung sind unabhängig von anderen Tests. Genial.

In [1] implementiert Ralf zuerst mittels TDD 1.0 und danach mittels TDD 2.0 die Kata “WordWrap”. Bei letzterer Vorgehensweise wird allerdings nur von der dritten Phase, Implementierung mittels TDDaiymi, Gebrauch gemacht. Zur Erinnerung noch einmal die aktualisierte Version von TDD:

image

Ganz bewusst wurde auf die beiden vorhergehenden Phasen verzichtet, da TDDaiymi der Schwerpunkt des Artikels war. Ralf ergänzt, dass die entstandene Struktur bereits in der Solve-Phase hätte entdeckt werden können.

Kritik TDD 1.0

Trotz disziplinierter Anwendung von TDD 1.0 führt dies nicht im Entferntesten zu Code, der leicht verständlich ist. Unter [3] findet man sowohl Tests als auch Produktionscode der Implementierung. Folgendes Code-Snippet zeigt nur den Produktionscode aus [3]. Leider wurde ausschließlich die komplette Implementierung eingecheckt, sodass man in der Git-History die einzelnen Schritte nicht erkennen kann.

Besser mit TDD 2.0

Folgendes Code-Snippet zeigt die Lösung aus [4], die mittels TDDaiymi erzeugt wurde.

Auffällig bei dieser Implementierung ist die domänenspezifische Trennung unter- schiedlicher Aspekte. Man kann anhand des Codes genau erkennen wie die Lösung funktioniert.

In [1] wird jeder Schritt von Rot auf Grün ganz genau von Ralf erklärt. In einer tabellenartigen Darstellung befindet sich auf der linken Seite immer der Test und auf der rechten Seite die Implementierung (bei TDDaiymi erneut der Test + Produktionscode im Test). Fantastisch.

Trotzdem fiel es mir nicht besonders leicht, die einzelnen Refaktorisierungen von Ralf nachzuvollziehen. Das lag vielleicht daran, dass ich mich schon vor einiger Zeit einmal an TDDaiymi versucht habe und daher eine gewisse Vorstellung darüber hatte, wie diese Methode anzuwenden ist. Da es jedoch kaum Literatur dazu gibt, war es sehr aufschlussreich zu sehen, wie Ralf dabei vorgeht. Noch genialer wäre ein Screencast, bei dem man Ralf bei seinem Vorgehen beobachten könnte. Und siehe da Smiley :

Zwar ist die Lösung in diesem Video nicht 1:1 dieselbe wie in dem dotnetpro Artikel [1], aber es hat mir auf jeden Fall unglaublich geholfen. Nachdem ich dann selbst mehrmals WordWrap mittels TDDaiymi übte, war es mir endlich möglich, folgende Aussage von Ralf nachzuvollziehen:

“Bei TDD 2.0 hingegen gibt es zunächst gar keinen Produktionscode. Da gibt es nur Tests – bis sich ein Muster herausschält. Man ist von vornherein also im Mustererkennungsmodus für die Refaktorisierung. Weil es eine Implementierungsrichtlinie für Grün gibt – schreibe Code zunächst in der Testmethode –, wird man quasi in die Refaktorisierung gezwungen.” [1]

Ich behaupte, dass man dieses Gefühl des Mustererkennungsmodus nur verstehen kann, wenn man TDDaiymi selbst mehrmals ausprobiert hat. Man ist ständig auf der Suche nach Wiederholungen, die auf neue Aspekte hindeuten könnten.

Gelerntes

Folgende Punkte aus [2] hat Ralf unter “Was ich gelernt habe” zusammengefasst:

- Refaktorisierung ist nicht mehr optional, sondern muss vorgenommen werden.
- Dopplungen in Testmethoden sorgen ganz natürlich dafür, dass Aspekte in Lösungsmethoden verpackt werden (DRY).
- Weitere Methoden entstehen nur bei Sensibilität für SRP.
- Es ist wirklich wichtig, Lösungen zuerst in der Testmethode zu implementieren. Nur so werden Aspekte sichtbar, die sonst in Lösungsmethoden untergehen würden.

Ich finde TDDaiymi weiterhin nicht unbedingt einfach. Das Video von Ralf plus der dotnetpro Artikel [1] helfen jedoch ungemein. Ralfs Erkenntnisse stimmen mit meinen überein.

Offene Fragen

Einige Fragen stellen sich mir jedoch weiterhin: Wie sieht TDD 2.0 in realen Anwendungen aus? Kommt TDDaiymi für die komplette Applikation zur Anwendung oder nur für Teilaspekte? Ist TDDaiymi nur für die Erforschung innerer Strukturen von Klassen?

Aussichten

Im nächsten Teil hoffe ich einige dieser Fragen beantworten zu können. Außerdem beschreibt Ralf zum einen was man eigentlich unter Design versteht, zum anderen wird anhand der BowlingGame Kata der komplette TDD 2.0 Zyklus vorgeführt.

Referenzen

[1] dotnetpro Artikel: Ab ins Grüne von Ralf Westphal http://bit.ly/1i79VMi
[2] XP Days 2012 Slides zu TDDaiymi von Ralf Westphal: http://bit.ly/1ln74kQ
[3] WordWrap mittels TDD 1.0 von Ralf Westphal: http://bit.ly/1bIxnd3
[4] WordWrap mittels TDD 2.0 von Ralf Westphal: http://bit.ly/19K8408

Weitere Referenzen aus [1]:

Robert C. Martin, The Craftsman 62 – The Dark path http://bit.ly/1kDOVS8
Robert C. Martin, Uncle Bob’s Blog, The Transformation Priority Premise (Leider offline)
Code Cop, Word Wrap Kata Variants, http://bit.ly/1j8OUDW
Keith Braithwaite, TDD as if you meant it http://bit.ly/1a9JhCZ
Keith Braithwaite, TDD as if you meant it (Video) http://bit.ly/K7kbc3
Gojko Adzic, Thought-provoking TDD exercise at the Software Crapftsmanship conference http://bit.ly/1iiTK10
Gojko Adzic, TDD as if you meant it – revisited http://bit.ly/1c8BYoX

Veröffentlicht unter Refactoring, Software Craftsmanship, TDD | Verschlagwortet mit , , | Hinterlasse einen Kommentar

TDD 2.0 – Problemanalyse, Lösungsfindung, Implementierung

[Update (10/12/2013): Rechtschreibung]

Schon mal bei einem Coding Dojo etwas frustriert gewesen, da absolut keine Lösung in Sicht war? Praktiziert eigentlich jeder Softwareentwickler TDD auf dieselbe Art und Weise? Kann bzw. muss eine so fundamentale Vorgehensweise wie TDD weiterentwickelt werden? Ralf Westphal meint ja!

Wer mich kennt, der weiß, dass ich ein Fanboy von Ralf Westphal bin. Warum? Ich finde, dass es nicht besonders viele Personen in meiner Branche gibt, die bestehende Dinge hinterfragen und vorantreiben. Ralf ist allerdings für mich genau einer dieser Menschen, die grundlegende Bereiche der Softwareentwicklung verbessern möchten. Ein Beispiel dafür ist die Testgetriebene Entwicklung, die vor ca. 10 Jahren von Kent Beck ins Leben gerufen wurde. Täglich stelle ich fest, dass diese Disziplin noch nicht wirklich in Wien (bzw. Österreich) bei der Entwickler-Community angekommen ist.

Auch bei aktuellen Konferenzen werden nach wie vor jede Menge Einführungsveranstaltungen zum Thema TDD angeboten. Von Universitäten und Fachhochschulen will ich gar nicht reden. OK, an eine Vorlesung erinnere ich mich, in der das Thema kurz einmal erwähnt, ja sogar demonstriert wurde. Unterm Strich obliegt es jedoch jedem selbst diese so wichtige Disziplin zu erlernen und ständig zu üben.

Ralf Westphal hat aus meiner Sicht eine sehr beeindruckende Artikelserie in der dotnetpro geschrieben, die meiner Meinung nach öffentlich kostenlos zugänglich gemacht werden sollte, um möglichst viele Entwickler damit zu erreichen. Im ersten Teil dieser Serie kritisiert er die gegenwärtige Praxis von TDD. Zum Teil entsprechen diese Kritiken meinen persönlichen Erfahrungen. Die beiden Hauptpunkte sind: mangelndes Refactoring, d.h. die dritte Phase von TDD wird nur marginal von Entwicklern durchgeführt, und die nicht vorhandene Trennung von Lösungsfindung und Implementierung.

Kritik: Mangelndes Refactoring

Warum funktionieren die ersten beiden Phasen, Red + Green, besser als die letzte? Diese Frage stellt sich auch Ralf. Ist es mangelndes Wissen bezüglich prinzipiengetreuen Programmierens? Fehlender Spaß an der Sache? Geht es einfach schlicht weg auch ohne? Es ist mit Sicherheit eine Kombination aller dieser Dinge.

Ich habe TDD so gelernt, dass man in der Red-Phase immer nur genau so viel Produktionscode schreibt, bis Tests grün sind. Dadurch vermeidet man Code zu schreiben, den man nur eventuell brauchen könnte. So entstehen Lösungen die dem KISS Prinzip entsprechen. Das Problem damit ist, dass die Verständlichkeit dadurch nicht gerade  erhöht wird. Natürlich entfernt man Duplikation und achtet darauf Magic-Numbers/Strings zu vermeiden; und klar ist es leichter, in KISS basierten Implementierungen Erweiterungen durchzuführen als in 1000-zeiligen Methoden. Jedoch muss man nach wie vor Codearchäologie betreiben um den Code verstehen zu können. KISS is not enough!

Mir persönlich stellt sich auch immer wieder die Frage: Wann habe ich genug Refactoring betrieben? Oder anders formuliert: Wann habe ich genug Struktur in meiner Implementierung untergebracht um Evolvierbarkeit zu ermöglichen und Nachvoll-ziehbarkeit für den nächsten Bearbeiter zu gewährleisten? Deshalb programmieren wir in der Arbeit ausschließlich zu zweit (und das nicht nur zur Fehlerbehebung bzw. wenn es Probleme gibt).

Der Punkt ist, es gibt keine klaren Regeln zur dritten Phase von TDD. Noch dazu ist Design aka Refactoring zum großen Teil subjektiv. Ralf ist der Meinung, dass fehlender Druck zum Refactoring ein Grund für die aktuell gelebte TDD-Praxis sein könnte. Dabei bezieht sich der fehlende Druck auf die Methode selbst.

Kritik: Fehlende Phase zur Lösungsfindung

Wenn man TDD betreibt dann muss einem eines ganz klar bewusst sein: TDD führt nicht automatisch zur Lösung eines Problems. Ohne Denken geht es einfach nicht! Schon öfters habe ich bei Coderetreats feststellen müssen, dass Entwickler beim Programmieren ins Stocken geraten. “Welchen Test schreiben wir denn jetzt? Uff, da müssen wir aber jede Menge umbauen!” Das Problem ist, dass wir gleichzeitig zu lösen und zu implementieren versuchen.

Ralf sagt dazu folgendes [1]:

Zwischen Testcode und Produktionscode liegt immer Nachdenken, das heißt die Entwicklung einer Lösung im Kopf des Programmierers. Wenn das jedoch während des Codierens stattfinden soll, ist der Prozess eingeschränkt. Dazu müsste der Programmierer präemptives Multitasking betreiben und immer wieder zwischen Codieren und Lösen wechseln. Das sind zwei kreative, um Hirnkapazität konkurrierende Tätigkeiten.

TDD 2.0

Wie sich vielleicht erahnen lässt, gehört die Trennung zwischen Lösungsfindung und der Implementierung (Red+Green+Refactoring) unter anderem zum Verbesserungsvorschlag von Ralf. Ebenfalls wird die Problemanalyse explizit der Lösungsfindung vorangestellt. Man erhält folgende drei Phasen für TDD 2.0:

image

Die Abbildung habe ich von Ralfs Blog geborgt. Man findet sie hier. Diese wird auch in der dotnetpro Artikelserie mehrmals verwendet.  Für Ralf handelt es sich dabei um den minimalen Softwareentwicklungsprozess je Inkrement. Weniger geht nicht!

Wenn man heutzutage TDD gelehrt bekommt, sei es durch erfahrene Entwickler, durch Bücher oder eventuell durch Videos im Web, wird ausschließlich die Refactoring-Phase zum Designen verwendet. Kent Beck schreibt in seinem Buch Test-Driven Development By Example:

1. Write a test. …
2. Make it run. …
3. Make it right. …

oder

First we’ll solve the ‘that works’ part of the problem. Then we’ll solve the ‘clean code’ part.

Dadurch entsteht Codestruktur relativ spät und überraschend. Auch ich habe es bis jetzt hauptsächlich so geübt, jedoch halte ich die Refactoring-Phase strikt ein. Schon alleine aus dem Grund weil sie mir einfach Spaß macht. Trotzdem entstehen dadurch Abstraktionen erst, wenn ich z.B. Duplikation entferne. Zu spät aus Ralfs Sicht. Warum hoffen, dass Struktur nur nach mehrmaligen Refactoring entsteht? Außerdem darf es niemals ausgelassen/vergessen/verschoben werden. Leider zeigt die Praxis jedoch Gegenteiliges.

Ralf meint:

Schluss mit Überraschungen!

In TDD 2.0 macht man sich schon in der Lösungsphase Gedanken zum Design. Durch tiefes Problemverständnis versucht man eventuelle Aspekte herauszuarbeiten, die in der Lösung vorkommen sollen. Wenn man bis jetzt immer einfach darauf los gecoded hat, dann kann es zu Beginn schon ein bisschen schwer fallen, die IDE zuerst vorab geschlossen zu lassen. Zunächst nur Zettel und Stift nehmen, die Lösung versuchen zu visualisieren und aussagekräftige Bezeichnungen zu finden. Verrückt oder?

Aber halt! Schalten wir einen Gang zurück. Man wäre gut beraten, die erste Phase in TDD 2.0 nicht auszulassen. Die ist nämlich absolute Voraussetzung zur Lösungsfindung. In dieser geht es darum, ein tiefes Verständnis für die Problemdomäne zu entwickeln. Hat man das Problem nicht verstanden, dann ist es natürlich auch nicht möglich eine Lösung zu finden. Klingt logisch oder? Ich kann mich noch genau an mein erstes Coderetreat erinnern. Bereits in der ersten Session wurde von meinem Pairing Partner folgendes gesagt: “Na schreib einfach einmal einen Test”. Ich habe mich dem Druck gebeugt und einfach mal drauf los getippselt. Nicht besonders hilfreich. Mehr darüber werde ich einmal in einem separaten Post zum Thema Coding Dojos und Coderetreats berichten.

Ich habe oft den Eindruck, dass es in der Natur des Entwicklers liegt, lieber in eine IDE zu starren als vorab das Problem zu diskutieren. Schon oft habe ich gemerkt, dass mein Pairing Partner lieber einmal drauflos tippen würde, anstatt mit mir das Problem näher zu analysieren. Dadurch würde man sich viel Zeit sparen, da man nicht ins Stocken gerät bzw. mitten in der Implementierung auf Dinge stößt, die in Folge einen beträchtlichen Umbau erfordern.

Bewusstes Zeit nehmen für alle drei Phasen, um das geht es in Wirklichkeit in TDD 2.0. Bevor man sich das nächste Mal an die Implementierung eines neuen Features heranwagt, könnte man doch mal folgende Checkliste beachten:

IMG_0359

Auf den dritten Punkt der Checkliste bin ich bisher noch überhaupt nicht eingegangen. Woher weiß man eigentlich, welcher Testfall der nächste ist. Meiner Erfahrung nach, wird diese Entscheidung von Entwicklern relativ ad hoc getroffen. Ich habe es eigentlich noch nie erlebt, dass vorab Testfälle von jemanden überlegt und nach Schwierigkeitsgrad priorisiert wurden. Ohne dem kann es während der Implementierung zum Stillstand kommen, da man nicht so recht weiß, welcher Test dann der nächste ist. Eindeutig ein Zeichen dafür, dass man zu wenig priorisiert hat. TDD 2.0 bietet jedoch hier die Möglichkeit in die früheren Phasen zurückzuspringen. Wenn man allerdings schon Probleme bei der Priorisierung hat, dann muss man höchstwahrscheinlich noch weiter an der Lösungsfindung bzw. an der Problemanalyse arbeiten.

Wie geht’s weiter?

Der aufmerksame Leser wird bemerkt haben, dass diese Zusammenfassung ausschließlich auf die Verbesserung einer der beiden Kritikpunkte eingeht, nämlich auf den der Trennung von Lösungsfindung und Implementierung. Druck zur Refaktorisierung wird weiterhin nicht durch die Methode selbst ausgeübt. Darüber werde ich in meinem nächsten Post berichten.

Vertiefung

Ralf hat glücklicherweise schon einige Artikel über seinen Blog veröffentlicht die ebenfalls diese hier zusammengefasste Thematik behandeln. Wem TDD interessiert und wer gerne ein paar Beispiele zu diesem Material hätte, dem sei dringend empfohlen Ralfs Beiträge zu lesen.

Sehr zu empfehlen sind auch die dazugehörigen Kommentare von Ralf. Also auch diese unbedingt lesen. Da gibts noch mal richtig viel Input und Erklärung zum Material.

Wer die originale dotnetpro Artikelserie kaufen möchte, der findet sie hier:

[1] Teil 1 (03/2013)

Veröffentlicht unter Refactoring, Software Craftsmanship, TDD | Verschlagwortet mit , , | Ein Kommentar

Lerngruppen @ Work | Teil 3

In Teil 1 beschreibe ich den Grund warum ich in der Arbeit Lerngruppen initiiert habe. Schon bereits nach kurzer Zeit konnte man Veränderung innerhalb der Abteilung erkennen. Darüber habe ich Teil 2 berichtet. In diesem Post beschreibe ich die eher etwas negativen Erfahrungen die ich bis hierhin gemacht habe.

Realität

Lerngruppen finden nach wie vor alle 14 Tage statt. Lernmaterialien werden nur sehr selten nach einer Woche ausgeschickt. Meistens wird beim Aussenden des Outlook-Termins der nächsten Study-Group etwas Vorbereitungsmaterial in Form einiger Links hinzugefügt. Das Organisieren der Lerngruppen habe ausschließlich ich übernommen. D.h. niemand (ein oder zwei Ausnahmen gab es) innerhalb der Abteilung meldet sich freiwillig um die nächste Study-Group vorzubereiten. Warum das so ist, konnte ich bis jetzt nicht wirklich erklären.

Das Visualisieren der Lerngruppenadministration wird derzeit auf einem Flip-Chart Blatt durchgeführt und sieht wie folgt aus:

image 

Diskussionen nach abgehaltenen Vorträgen kommen nicht wirklich zu Stande. Hin und wieder werden (meistens von den gleichen Personen) ein paar Verständnisfragen gestellt. Positiv anzumerken ist, dass von jedem innerhalb der Abteilung schon mindestens einmal eine Study-Group übernommen worden ist.

Ab und an waren sogar wirklich ausgesprochen gut vorbereitete Lerngruppen dabei. Meines Erachtens waren Study-Groups dann am erfolgreichsten, wenn der Vortragende sich die Mühe gemacht hat, kleine Workshops in seine Präsentation einzubauen. Es gab Termine wo man in Kleingruppen oder aber auch alleine kleine Aufgaben erledigen durfte.

In der nächsten Abbildung sieht man einen Übungsteil in Aktion.

image

In der Lerngruppe ging es um das Thema „Werte“ und gehörte meines Erachtens zu den besten bis jetzt organisierten Terminen. Leider gibt es auch Abteilungsmitglieder die nichts mit diesen Workshops anfangen können. D.h., wenn alle anderen am Zusammenarbeiten sind, wird dann hartnäckig beim Mittun ausgesetzt.

Fazit: Mein Bauchgefühl sagt mir, würde ich aufhören die Lerngruppen zu organisieren, würden diese künftig nicht mehr stattfinden.

Naive Annahme

Ich halte Weiterbildung in meiner Branche nicht nur für unbedingt notwendig, sondern ich habe einfach Spaß daran, tägliches Neues zu lernen. Das war natürlich nicht immer so in meinem Leben. Seitdem ich jedoch meine Leidenschaft für die Softwareentwicklung entdeckt habe, hat sich auch mein generelles Lerninteresse drastisch erhöht. Eine Unterscheidung zwischen Hobby und Beruf gibt es bei mir nicht mehr.

Deshalb war ich besonders glücklich darüber, dass unser Abteilungsleiter diese Lerngruppen genehmigt hatte. Gemeinsam mit dem Team lernen. Großartig. Allerdings musste ich nach einiger Zeit feststellen, dass hauptsächlich ich Themen für die Study-Group vorbereitete. Das war eigentlich ok für mich. Leider arteten die Lerngruppen jedoch zu reinen Frontalvorträgen aus.

Diskussionen fanden nur noch vereinzelt statt. Ausgeschickte Materialien zur Vorbereitung wurden weitestgehend ignoriert. Das frustriert natürlich. Warum ist das so? Lernen meine Kollegen nicht genauso gerne wie ich? Sind die Themen nicht interessant genug?

Ohne Vorbereitung gibt es keine Diskussion. Ohne Diskussion gibt es keine Verbesserung der Kommunikation innerhalb des Teams. Was mache ich also falsch?

Erst vor kurzem hatte ich ein Aha-Erlebnis nachdem ich Ralf Westphals tollen Post zum Thema Slack gelesen hatte. Wer den noch nicht kennt, sollte diesen unbedingt jetzt studieren und dann wieder zu diesem Blog zurückkehren.

Es war leider naiv von mir zu glauben, dass nur weil uns unser Abteilungsleiter offiziell Zeit und Raum für gemeinsames Lernen zur Verfügung stellt auch jeder aktiv daran teilnehmen würde.

Wenn man seinem Team eine tolle Bibliothek an Sachbüchern bereitstellt, heißt es ja auch noch lange nicht, dass diese auch tatsächlich gelesen werden. Das habe ich jetzt begriffen. Was kann ich also tun, um meine Kollegen dazu zu motivieren sich auf Lerngruppen vorzubereiten?

Ich werde es auf jeden Fall mit Ralfs Vorschlägen probieren:

„Mein Vorschlag: Die Nutzung von Slack sollte immer wieder nachgefragt werden. Man muss an den Menschen ziehen. Pull ist also nicht nur für die Softwareentwicklung ein wichtiges Prinzip. Auch die Mitarbeiterentwicklung braucht es. Immer wieder muss der Slack-Geber klar machen, dass er wünscht, dass der Spielraum genutzt wird.

Fragen wie “Warum hast du den Slack nicht genutzt?” sind da allerdings weniger hilfreich als “Was hast du in deinem Slack gemacht?” Erstere sind nämlich wieder mehr oder weniger subtil drohend/kontrollierend, Letztere hingegen interessiert und in sich wiederum freistellend.

Slack-Nutzung vorleben und Slack-Nutzung interessiert nachfragen, das scheint mir sehr wichtig, um Menschen anzuleiten, mit Freiräumen umzugehen.

  • Was hast du zuletzt “erforscht” in der Zeit, die dir das Unternehmen dafür bietet?
  • An welchem Fach-/Sachbuch liest du gerade, das du dir von dem Literaturbudget des Unternehmens gekauft hast?
  • Was hast du auf der letzten Fortbildung gelernt, die die das Unternehmen ermöglicht hat?
  • Wie hast du deinen Entscheidungsspielraum genutzt, den dir das Unternehmen bietet?

Das Medium, um Zug in dieser Weise auszuüben, ist für mich “die Runde”, also ein ungezwungenes, allerdings fokussiertes Treffen. Zeit für solche Runden ist im Wochenkalender für alle vorzusehen. Das ist Führungsaufgabe. Und da wird dann nachgefragt, ausgetauscht und Slack gelebt.“

Investition

Das Thema Softwareentwicklung ist so breitgefächert, sodass es eine ganze Menge zu lernen gibt. Damit meine ich nicht nur die technischen Dinge, sondern vielmehr die „soften“ Themen. Das Entwickeln von Software ist Teamarbeit und auch das Arbeiten im Team muss verstärkt gelernt und geübt werden.

Ich bin der Meinung, dass jeder der in dieser Branche tätig ist, aktiv und bewusst in seiner Freizeit an sich und seinen Fähigkeiten arbeiten muss.

Wenn man dann noch zusätzlich die Möglichkeit bekommt, im Team miteinander zu lernen, dann sollte man das unbedingt ausnutzen und wertschätzen und jede einzelne Minute davon genießen. Denn eines sollte jedem bewusst sein, die untere Hälfte in der folgenden Abbildung ist auf jeden Fall die sinnvollere und meiner Meinung nach auch die unterhaltsamere.

Peer learning vs Lecture

Das Bild habe ich mir von Staffan Nöteberg geborgt: http://twitpic.com/c9l1zx

Veröffentlicht unter Lerngruppen | Verschlagwortet mit , | Ein Kommentar

Lerngruppen @ Work | Teil 2

Im ersten Teil dieser dreiteiligen Serie zum Thema Lerngruppen in der Arbeit beschreibe ich den Grund warum ich diese Art von Treffen innerhalb unserer Abteilung vorgeschlagen habe. Ohne große Überzeugungsarbeit genehmigte mein Chef diese tolle Möglichkeit um im Team miteinander zu lernen. Nachfolgend beschreibe ich zum einen wie ich die Organisation dieser Lerngruppen handhabe, zum anderen wie die ersten beiden Treffen abliefen und welche Auswirkungen sie hatten.

Die Wand

Beim Einführen der Lerngruppen hatte ich eine genaue Vorstellung darüber, welche Themen die Kommunikation fördern könnten. Außerdem wollte ich mein über die Jahre aufgebautes Wissen bezüglich Agiler Softwareentwicklung an meine Kollegen weitergeben. Da ich zur damaligen Zeit bereits einiges an Material über Visualisierung am Arbeitsplatz gelesen hatte und mir die Vorteile daher bewusst waren, nahm ich die Administration der Lerngruppe als Anlass, unsere erste Informationswand innerhalb der Abteilung aufzubauen. Nichts Aufwendiges. Eine simple Pinnwand, die zum damaligen Zeitpunkt sowieso ausschließlich als Ersatzkleiderhaken diente.

image image

Mir war folgendes sehr wichtig: Jeder sollte zu jedem beliebigen Zeitpunkt sehen können, welche Themen zur Auswahl stehen und welche bereits abgearbeitet wurden. Man sollte erkennen können, wer die nächste Lerngruppe organisiert und ob derjenige bereits Lernmaterialien zur Verfügung gestellt hat. Kurz gesagt, die Administration sollte komplett transparent ablaufen. Nicht versteckt in irgendeinem Programm.

Der Initialpool an Themen wurde von mir an die Wand gepinnt. Darunter waren z.B.: Einführung in die Agile Softwareentwicklung, SOLID-Prinzipien, Einführung in XP, Einführung in Regular Expressions, Einführung in Ruby, Wie funktioniert unser Gehirn, etc. zu finden. Ein Mischmasch aus technischen als  auch „soften“ Themen. 

Nach den ersten paar Lerngruppen sah unsere Informationswand wie folgt aus:

image image

Die erste Lerngruppe

An die erste Lerngruppe kann ich mich noch ganz genau erinnern. Sie wurde von unserem Abteilungsleiter übernommen. Ober sich dazu verpflichtet gefühlt hat? Er nahm diesen Termin als Anlass um uns die Idee eines Projekts zu präsentieren an dem er gerade tüftelte.

Ich war etwas enttäuscht darüber, dass es kein von mir vorgeschlagenes Thema war. Egal. Eine Regel der Lerngruppe war, dass jeder über Themen reden könne, die einem interessieren. Schön wäre es jedoch gewesen, wenn es nichts mit der Arbeit zu tun gehabt hätte. Damit wollte ich bezwecken, dass meine Kollegen endlich einmal etwas außerhalb ihrer gewohnten Arbeitsumgebung zum Thema Softwareentwicklung vermittelt bekommen. Nichts desto trotz war ich froh darüber, dass die Lerngruppe ins Rollen kam. Außerdem wollte ich nicht schon in der ersten Sitzung jemanden bezüglich seines Themas bevormunden, noch dazu wenn es sich dabei um meinen Chef handelte.

Es gab sogar einiges an Material was man vorher studieren konnte. Dies diente jedoch nicht ausschließlich der Lerngruppe zur Vorbereitung sondern auch als Konzept für die eigentliche Präsentation seiner Idee vor dem Vorstand des Unternehmens.

Meine erste Lerngruppe

Die zweite Lerngruppe wurde von mir übernommen. Mit den Hauptzielen Kommunikation und Wissensweitergabe im Hinterkopf wählte ich das Thema: „Eine Einführung in Kanban“. Als großer Fan von Henrik Kniberg und beeindruckt von der Art und Weise wie er Themen präsentiert, nahm ich eines meiner absoluten Lieblingsbücher von ihm „Lean from the Trenches“ als Grundlage für meine Präsentation.

Im Buch findet man eine Case Study über ein größeres Projekt und wie sich mittels Kanban Kommunikation in Teams fördern lässt. Durch ständiges Reflektieren über die getane Arbeit, findet man Möglichkeiten, wie sich alle zusammen verbessern können. Wurzelproblemanalyse ist hier das Zauberwort.

Folgende Aufzeichnung von Henrik diente mir als weitere Grundlage für die Lerngruppe:

Kanban and Scrum – making the most of both – Henrik Kniberg from Øredev on Vimeo.

Die zugehörigen Slides zum Video sind ebenfalls online zu finden. Damit sich meine Teamkollegen auch auf das Treffen vorbereiten konnten, schickte ich nach einer Woche den Wiki-Eintrag zum Thema Kanban via Mail aus. In diesem findet man die wichtigsten Begriffe kurz beschrieben. Meines Erachtens ausreichend Material um über das Thema nach meinem Vortrag zu diskutieren.

Zu Beginn meiner Lerngruppe fragte ich meine Kollegen, woran sie sich aus dem Wiki-Eintrag erinnern konnten. Diese Schlagworte hielt ich auf einem Flip Chart fest. Damit konnte ich während meines Vortrags immer wieder auf diese verweisen und den Zusammenhang zu meiner Präsentation herstellen. Soweit ich mich erinnern kann, fanden alle Teilnehmer an meinen Vortrag großen Gefallen. Doch ich hatte keine Vorstellung darüber, was ich mit dieser Lerngruppe ins Rollen bringen würde. Zwar nicht unmittelbar danach, jedoch nach kurzer Zeit sah unser Abteilungsbereich wie folgt aus:

image image

image image

Ich würde niemals behaupten, dass wir Kanban nach dem Buch leben, nicht im Entferntesten. Jedoch helfen die Whiteboards dabei, Arbeitsvorgänge zu visualisieren, die Kommunikation innerhalb des Teams zu verbessern und Transparenz zu schaffen im Sinne „Wer tut gerade Was“. Damit wurde der erste Schritt in die richtige Richtung getan. Wo es vorher keine Kommunikation gab, wird jetzt mehrmalig am Tag vor dem Whiteboard miteinander diskutiert.

Wie geht es weiter?

Bis hierhin könnte man annehmen, das Lernen im Team Spaß machen sollte. Es gibt sogar positive, sichtbare Auswirkungen im Arbeitsalltag. Leider habe ich eine grundsätzlich falsche Annahme getroffen. Darüber und inwiefern sich die Realität zur ursprünglichen Idee der Lerngruppen unterscheidet, berichte ich im nächsten Post.

Veröffentlicht unter Lerngruppen | Verschlagwortet mit , | Ein Kommentar

Lerngruppen @ Work

Kontext

Ich arbeite nun schon etwa 6 Jahre für dasselbe Unternehmen. Was genau dessen Dienstleistungen und Produkte sind, kann man hier nachlesen. Die Abteilung für die ich arbeite besteht derzeit aus neun Personen und nennt sich „New Technologies“. Wie der Name schon erahnen lässt, arbeiten wir mit (relativ) neuen Technologien. Folgende Abbildung zeigt die derzeitige Situation innerhalb der Abteilung bezüglich Verantwortlichkeiten:

image

Grundsätzlich gibt es eine Unterteilung in ein Java- (braun) und in ein .Net- (gelb) Team. Personen, die hauptsächlich miteinander zu tun haben besitzen die gleiche Farbe. Ich gehöre zu den rot-markierten Kreisen im .Net Bereich, habe allerdings auch schon im Java-Team gearbeitet. Wie man nur unschwer erkennen kann, hat eine Person äußerst viele Verantwortlichkeiten. Dabei handelt es sich um den NT-Abteilungsleiter, der gleichzeitig auch Bestandteil des Java-Teams ist.

In der folgenden Abbildung sieht man, dass unsere Abteilung aus sieben Entwicklern, einer Testerin und einer Business-Analystin besteht. Soviel zur derzeitigen Abteilungskonstellation.

image

Warum Lerngruppen?

Vor etwas mehr als einem Jahr, habe ich eine gewisse Unruhe innerhalb der Abteilung festgestellt. Bei einigen Personen hatte sich ein gewisser Frust aufgestaut, auch bei mir. Eine Hauptursache dafür war mangelnde Kommunikation innerhalb der gesamten Abteilung. Zur damaligen Zeit war es auch so, dass alle Personen ihre Aufgaben ausschließlich alleine umgesetzt haben.

Wenn man in unsere Abteilung kam, dann hat man eigentlich nur selten Personen miteinander arbeiten sehen. Warum das so war? Ich vermute eine Kombination aus Charaktereigenschaften (die meisten eher introvertiert), Gewohnheit, Frust und eventuell auch Angst. Ich stellte mir also die Frage wie ich Kommunikation innerhalb der Abteilung fördern und Personen wieder dazu motivieren könnte, verstärkt miteinander zu arbeiten?

Bei einer Nachmittagskaffeerunde habe ich dann also einmal das Thema „Lerngruppe“ erwähnt. Bis auf den Abteilungsleiter waren alle Personen anwesend. Sehr überrascht darüber, dass diese Idee bei allen Abteilungsmitgliedern positiv ankam, beschrieb ich ihnen meine Vorstellung eines solchen Zusammentreffens.

Vision einer Lerngruppe

Jede Woche bereitet ein Mitarbeiter ein Thema vor, dass er dann in der Gruppe im Rahmen eines kurzen Vortrags (ca. 30 Minuten) präsentiert. Im Anschluss soll es zur Vertiefung durch Diskussion kommen. Dabei können eventuell entstandene Fragen geklärt, oder sogar Möglichkeiten zur Adaptierung innerhalb der Abteilung gefunden werden. Kann man das Gelernte vielleicht direkt anwenden? Wenn nicht, was wäre notwendig um es in Gang zu bringen?

Das Thema ist beliebig. Jeder kann präsentieren was er möchte. Wichtig dabei ist, dass Material für die restlichen Teilnehmer vom Vortragenden zur Verfügung gestellt wird, damit jeder sich vorbereiten kann. Das individuell Gelernte soll ja zur Diskussion anregen um das eigentliche Ziel zu erreichen, nämlich Kommunikation innerhalb der Abteilung zu fördern.

Außerdem muss die Lerngruppe während der offiziellen Arbeitszeit abgehalten werden. Dafür ist natürlich die Zustimmung des Abteilungsleiters einzuholen.

Zustimmung ohne Einwände

Mit dem von mir vorgeschlagenen Ablauf waren alle einverstanden. Wir einigten uns darauf, die Zustimmung des Abteilungsleiters im nächsten Abteilungsmeeting einzuholen. Wer aber konkret fragen sollte wurde nicht vereinbart.

Da saßen wir nun in diesem Meeting und nachdem die routinemäßige Informationsrunde vorbei war und sich keiner zur Lerngruppe äußerte, fasste ich mir ein Herz und übernahm die Initiative. War ja auch schließlich mein Vorschlag, also Zähne zusammenbeißen und los.

Wie erwartet war der Abteilungsleiter mit der Idee einverstanden, korrigierte jedoch den Rhythmus von einer auf zwei Wochen, mit der Begründung, dass der Aufwand zu groß wäre. Äußerst glücklich über die Zustimmung unseres Chefs, konnten wir alle mit den neuen Rahmenbedingungen leben.

Weiterer Verlauf

Die ersten Schritte zur verbesserten Kommunikation innerhalb des Teams wurden erfolgreich gesetzt. Im nächsten Post berichte ich über die Organisation der Lerngruppen und inwieweit sich die Realität von meiner ursprünglichen Vorstellung dieser Treffen unterscheidet.

Veröffentlicht unter Lerngruppen | Verschlagwortet mit , | 3 Kommentare

Software Wartung und Evolution | Portierung eines Altsystems von PL/I nach Java

Im Rahmen der Lehrveranstaltung Software Wartung und Evolution musste ich ein PL/I Programm analysieren, dokumentieren und nach Java portieren. Im restlichen Post beschreibe ich Schritt für Schritt, wie ich bei dieser Übung vorgegangen bin. Ich bin in meiner bisherigen IT-Laufbahn noch nie mit PL/I in Berührung gekommen und daher ein absoluter Beginner bezüglich dieser Programmiersprache. Nachdem ich das zu untersuchende Programm von der Lehrveranstaltungshomepage heruntergeladen und kurz überflogen hatte, war meine erste Idee im Web nach einem PL/I Compiler zu suchen um ein paar Codebeispiele selbst zu tippen, zu kompilieren und auszuführen.

Nach ein bisschen googlen musste ich leider feststellen, dass diese Programmiersprache nicht mehr wirklich supported bzw. weiterentwickelt wird. Allerdings hatte ich Glück eine Demo-Version einer PL/I-Programmierumgebung von IBM in einem Forum zu finden.  Ich habe die Datei pliwintb.zip heruntergeladen und in einer VMWare unter Windows XP installiert. Nach kurzer Einarbeitungsphase, habe ich das erste “Hello World”-Programm erfolgreich kompiliert, ge-linkt und ausgeführt.

PL/I Hello World Demo

 

 

 

 

 

 

Mit Hilfe des Buchs “Das neue PL/I” habe ich mich ein bis zwei Stunden in PL/I eingelesen und ein paar Beispielprogramme abgetippt und ausgeführt. Danach habe ich begonnen, das für die Uni-Übung zu analysierende Programm Zeile für Zeile selbst zu implementieren und zu testen. Falls mir Schlüsselwörter und Sprachkonstrukte noch nicht bekannt waren, habe ich diese einfach in dem weiter oben erwähnten Buch nachgeschlagen. Falls mir dann immer einige Dinge noch unklar waren, habe ich einfach ein kurzes Programm geschrieben, um die mir noch unverständliche Funktionalität zu testen.

Die folgende Aufgabenstellung und der zugehörige Tipp ist von der Lehrveranstaltungs-hompage entnommen. Danach gebe ich eine Ausführliche Dokumentation des zu portierenden PL/I-Programmes.

Aufgabenstellung

Im Rahmen der Analyse und Portierung eines Altsystems von PL/I nach Java, konnte der Großteil der Arbeit bereits erfolgreich durchgeführt werden. Ein kleiner Programmteil konnte jedoch – mangels Dokumentation – noch nicht analysiert und portiert werden.

Ihre Aufgabe ist es, den verbliebenen Teil des PL/1 Sourcecodes zu analysieren, dessen Funktionsweise zu erklären und den Sourcecode geeignet zu re-dokumentieren. Weiters soll die Funktionsweise des PL/1 Programms in Java übersetzt/portiert werden.

Hier ein von mir erstelltes Gist auf Github des Progamms: PROGRAMXYZ.pli

Tipps

Ev. gibt es einen guten Grund warum die ursprünglichen Programmierer genau diesen Programmteil nicht dokumentiert hatten.

Es ist nicht notwendig (und unter Umständen auch nicht ohne weitere Änderungen möglich) den bestehenden Code lauffähig zu bekommen. Sollten Sie dennoch versuchen, den Code direkt zu übersetzen und Erfolg dabei haben, können Sie Zusatzpunkte erlangen.

Codeanalyse

Nachdem ich das Programm genau analysiert und einige mögliche Benutzereingaben auf altmodische Weise, nämlich mit Zettel und Bleistift, durchgespielt hatte, wurde die Funktionalität des Programms eindeutig. Es handelt sich um das bekannte Spiel “Master-Mind”. 

In den folgenden Absätzen beschreibe ich die Teile des Quellcodes, von denen ich nicht wusste, was sie genau tun und wofür sie da sind. Um meiner Beschreibung besser folgen zu können, würde ich empfehlen, den kompletten Quellcode des Programms herunterzuladen und jeweils die von mir beschriebene Zeile nachzuschlagen.  

Aufgrund der ersten Zeile des Programms weiß der Compiler (zumindest der von IBM) alles über deutsche Buchstaben: 

*process names ('äöüß', 'ÄÖÜ$');

Der folgende Programmausschnitt definiert die Methodensignatur des Hauptprogamms. Man kann diese Methode mit der Main-Methode eines jeden lauffähigen Java-Programms vergleichen Bei dem Schlüsselwort reorder handelt es sich um eine Optimierungsangabe für den Compiler. Es bewirkt, dass der Compiler gewisse Anweisungen beliebig umordnen kann, wenn dadurch die Ausführungszeit verkürzt wird.

 PROGRAMXYZ:
 procedure options (main reorder);

Für alle möglichen Farbeingaben wird ein eigener Datentyp definiert. Hier wäre die Angabe von tatsächlichen Farben statt Optionen für die Benutzung des Programms “schöner” gewesen. Anstatt vom Benutzer Optionen zu verlangen, wäre die Angabe von z.B. “grün blau rot grün” noch spielgetreuer gewesen:

 define ordinal COLOR 
    (INVALID, OPTION1, OPTION2, OPTION3, OPTION4, OPTION5, OPTION6);

Für die Tipps des Benutzers und für die "ausgedachte" Wahl (Code) des Computers werden als Datentypen Matrizen verwendet.

 dcl Code dim (4) type COLOR;
 dcl TIP dim (4) type COLOR;

Nach der Deklaration aller notwendigen Variablen wird durch den Aufruf der Methode RANDOM die “Code”-Matrix befüllt. Dabei handelt es sich also um die vom Spieler zu erratene Farbwahl des Computers. Per Definition wird die RANDOM-Methode vier Mal aufgerufen, da es sich um eine Matrix mit der entsprechenden Dimension handelt. Dabei handelt es sich mein Meinung nach um eine äußerst interessante Funktionalität, dich ich so in noch keiner anderen Programmiersprache gesehen habe.

 Code = RANDOM();

RANDOM-Funktion unter die Lupe genommen:

Diese Methode gibt eine gültige Farboption, die zufällig gewählt wird, zurück. Dieser Zufallsmechanismus funktioniert wie folgt: die von PL/I zur Verfügung gestellte random-Funktion ergibt eine Zahl zwischen 0 und 1, wobei 0 und 1 ausgeschlossen sind. Wenn man diese Zahl nun mit sechs multipliziert, ergibt das natürlich eine Zahl zwischen 0 und 6. Um diese als Index für die COLORCODE Matrix verwenden zu können, benötigt man die PL/I-Funktion trunc, die einfach den Nachkommateil der Zahl verwirft.

 RANDOM:
 procedure returns (type COLOR);
   dcl Zahl float init (0) static;
   dcl COLORCODE dim (0:5) type COLOR nonasgn static
      init (OPTION1, OPTION2, OPTION3, OPTION4, OPTION5, OPTION6);

   if Zahl = 0
      then Zahl = random(time());
      else Zahl = random();
   return (COLORCODE(trunc(Zahl*6)));
 end RANDOM;  

Nach dem initialsieren der Code-Matrix, d.h. der Farbwahl des Computers,  ist der Benutzer am Zug. Seine Eingabe wird innerhalb einer Endlosschleife im Hauptprogramm entgegengenommen.

 do loop;
    display ('TIP?') reply (ANSWER);
    ...
    end;

Danach wird vom Programm versucht, die Benutzereingabe in einen gültigen Tipp umzuwandeln. Dabei wird versucht, die Eingabe zu parsen und in eine Matrix zu konvertieren. Diese Aufgabe übernimmt wiederum eine kurze Subroutine namens TRANSLATION die vom Hauptprogramm aus aufgerufen wird.

call TRANSLATION (ANSWER, TIP);

TRANSLATION-Funktion unter die Lupe genommen:

Der erste Schritt ist das Initialisieren der TIP-Matrix mit dem Wert INVALID. Danach wird die Benutzereingabe, mittels PL/I zur Verfügung gestellter translate-Funktion, in Großbuchstaben umgewandelt.  Interessant sind auch die beiden PL/I-Funktionen verify und search. In Ersterer wird das erste Argument darauf hin untersucht, ob es ausschließlich aus den Zeichen des zweiten Arguments besteht. Das dritte Argument gibt die Position an, ab der diese Bedingung Gültigkeit erlangen soll. Verify gibt entweder 0 zurück, sofern alle Zeichen gültig sind, oder die Position des ersten nicht gültigen Zeichens. Die sehr ähnliche search-Funktion durchsucht das erste Argument nach dem ersten Vorkommnis des als zweiten Argument übergebenen Zeichens.

Trans

Sobald die notwendigen Positionen (für Letter und Blank) ermittelt worden sind, wird mittels substring-Methode, das sich durch die Positionen ergebende Wort, aus der Benutzereingabe herauskopiert. Dieses wird danach auf Gültigkeit hin überprüft, d.h. handelt es sich um eine valide Farboption, und gegebenenfalls an der entsprechenden Position in der Tipp-Matrix gespeichert. 

 TRANSLATION:
 procedure (ANSWER, TIP);
/* Variablen-Deklaration */



TIP = INVALID; if length(ANSWER) = 0 then return; S = translate(ANSWER,'ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ', 'abcdefghijklmnopqrstuvwxyzäöü'); Blankpos = 1; do I = 1 to 4; Letterpos = verify(S, ' ', Blankpos); if Letterpos = 0 then leave; Blankpos = search(S, ' ', Letterpos); if Blankpos = 0 then Blankpos = length(S)+1; do F = OPTION1 upthru OPTION6; if substr(S, Letterpos, Blankpos-Letterpos) = ordinalname(F) then TIP(I) = F; end; end; end TRANSLATION;

Nach dem Aufruf der TRANSLATION-Methode hat man eine initialisierte Tipp-Matrix die nun auf Richtigkeit hin überprüft werden kann. Die any-Funktion wird von PL/I zur Verfügung gestellt und erwartet als Argument eine Matrix. Es wird für jedes Element in TIP überprüft ob es den Wert INVALID besitzt. Als Ergebnis erhält man eine neue Matrix die nur aus Bit-Werten besteht. Sofern eines der Felder in der neuen Matrix auf den Wert Wahr (1’b’) gesetzt wurde und somit ursprünglich den Wert INVALID hatte, ergibt die any-Funktion ebenfalls wahr (OR-Verknüpfung).

 if any(TIP = INVALID) then

display ('INVALID COLOR!');

Die all-Funktion verhält sich ähnlich zur any-Funktion jedoch handelt es sich hier um eine AND-Verknüpfung, d.h. alle Elemente der übergebenen Matrix müssen den Wert Wahr (‘1’b) besitzen. In diesem Fall muss jede Farboption des Tipps der jeweiligen Farbeoption der Code-Matrix entsprechen. Ist das der Fall, handelt es sich um einen richtigen Benutzertipp und die do-Schleife wird unterbrochen und das Programm beendet.

 if all(TIP = Code) 
    then leave;

Ansonsten wird mittels einer weiteren Subroutine namens EVALUATION diejenigen Treffer des Tipps ermittelt, die entweder die richtige Farbe und richtige Position (HITS) oder nur die richtige Farbe (HITS_OTHER_POSITION) besitzen. 

 do loop;
    ...
    call EVALUATION (Code, TIP, HITS, HITS_OTHER_POSITION);
    ...

EVALUATION-Funktion unter die Lupe genommen:

 EVALUATION: 
 procedure (Code, Tip, HITS, HITS_OTHER_POSITION);
   
/* Variablen-Deklaration */
HITS = sum(Tip = Code); HITS_OVERALL = 0; do F = OPTION1 upthru OPTION6; HITS_OVERALL += min(sum(Tip = F), sum(Code = F)); end; HITS_OTHER_POSITION = HITS_OVERALL - HITS; end EVALUATION;

Wie auch schon bei der any- und all-Funktion, handelt es sich bei dem übergebenen Argument der von PL/I zur Verfügung gestellten sum-Funktion, um eine Bit-Matrix. Wenn also die in der Tip-Matrix eingetragenen Farboptionen mit denen der in der Code-Matrix übereinstimmen, werden alle Elemente die den Wert Wahr (1’b’) besitzen, aufsummiert (Hits). Um die Anzahl der Treffer zu berechnen, bei denen nur die Farbe korrekt ist, wird zuerst in einer do-Schleife für jede mögliche Farboption, die Anzahl der gesamten Treffer ermittelt und aufsummiert. Danach werden von den gesamten Treffern die Hits abgezogen und man erhält genau die Treffer bei denen nur die Farbe korrekt ist.

EVAL

Programmterminierung

Die Endlosschleife des Hauptprogamms wird erst dann unterbrochen, bis die Tipp- und die Code-Matrix übereinstimmen oder der Benutzer eine leere Eingabe  macht. D.h. der Benutzer spielt so lange, bis er die richtige Kombination erraten hat oder bis er das Spiel durch eine leere Zeichenkette abbricht.

Zusatzpunkte

In der Aufgabenstellung findet man unter Tipps den Hinweis, dass das zu untersuchende Programm nicht ohne Änderungen lauffähig sei. Zusatzpunkte könne man dadurch erreichen, indem man die Ursache für für das Nichtfunktionieren herausfindet und dann das Programm so abändert, damit es lauffähig wird.

Was mir beim ersten Überfliegen des Programms sofort aufgefallen ist, ist die Namensgleichheit der selbst erstellten Funktion RANDOM und der entsprechenden PL/I-Funktion. Da diese Funktion leider nicht mit meinem gefunden Compiler funktioniert, konnte ich das Programm auch nicht lauffähig bekommen. Allerdings habe ich ein kurzes Programm geschrieben, dass zumindest zeigt, dass eine solche Namensgleichheit nicht vorkommen darf.

Programm für das Aufzeigen eines Namenkonflikts

 

 

 

 

 

 

 

Fazit

Obwohl es sich bei PL/I um eine doch etwas in die Jahre gekommene Programmier-sprache handelt, finde ich doch einige Sprachkonstrukte sehr interessant. Zum Beispiel die Matrizen-Operationen wie any oder all finde ich äußerst gut lesbar und leicht zu verstehen.

Veröffentlicht unter University | Verschlagwortet mit | Ein Kommentar

Refactoring Kata mit IntelliJ – Jason Gorman’s Assault Course

Vor kurzem habe ich mich dazu entschlossen, auf eine neue IDE umzusteigen. Da ich die letzten Jahre hauptsächlich mit Eclipse und NetBeans gearbeitet habe und wirklich jeder meiner Rock Star Programmer IntelliJ empfiehlt, war es höchste Zeit für mich, diese IDE einmal auszuprobieren. Da ich wirklich ein großer Eclipse Fan bin habe ich bis jetzt keinen sonderliches Verlangen danach verspürt, die Entwicklungsumgebung zu wechseln. Die große Anzahl an Shortcuts – ich steh besonders auf Strg + 3 – und die außerordentlich gute Integration von Maven mittels des m2eclipse-Plugin, machte Eclipse zu meiner absoluten Lieblings-IDE (zumindest bis vor kurzem).

Ich habe IntelliJ jetzt seit ungefähr zwei bis drei Wochen intensiv getestet. Mein Hauptaugenmerk lag dabei auf den Editor-Qualitäten, der Maven- und Groovy-Integration und bis jetzt bin ich absolut begeistert. Die Shortcut-Möglichkeiten sind um einiges ausgereifter als in Eclipse. Ich habe mittels Jason Gorman’s vor kurzem geposteten Assout Course, einige der tollen Refactorings von IntelliJ getestet. Der folgende Screencast zeigt mich beim Üben des Refactoring Katas in IntelliJ:

My version of Jason Gorman’s Refactoring Kata using IntelliJ

 

 

 

 

 

 

 

Zum Vergleich hier der Screencast von Jason Gorman mittels Eclipse:

Aussault Course by Jason Gorman using Eclipse

 

 

 

 

 

 

Den Source-Code des Kurses kann man hier downloaden.

Ich mache einige Dinge ein bisschen anders als Jason Gorman. Zum Beispiel führe ich Extract-Method-Refactorings immer von unten nach oben durch, da ich gerne meinen Source-Code von oben nach unten, d.h. alle Methoden in der entsprechenden Aufrufreihenfolge, organisiere. Das erlaubt mir meinen Quellcode wie ein Stückchen Prosa zu lesen. Diese Idee stammt übrigens aus Robert C. Martin’s Buch “Clean Code”.

Zuerst werden ein paar Methoden aufgrund von Verantwortlichkeiten in andere Klassen verschoben und extrahiert. Danach wird ein switch-Block durch den Einsatz des Strategy-Patterns ersetzt. Ich habe für das Projekt auch ein Github Repository angelegt. Von dort kann man den Ausgangszustand des Katas für IntelliJ clonen. Nachdem ich mit einem kompletten Durchgang fertig bin, “reverte” ich immer alle Files in den Ausgangszustand um das tägliche Üben zu erleichtern.

Fazit: IntelliJ rockt! Btw. Strg + 3 ist in IntelliJ Strg+Shift+A.

Veröffentlicht unter Kata, Programming, Refactoring | Verschlagwortet mit | Hinterlasse einen Kommentar