07
Nov 13

Ein Tag im Leben des agilen Entwicklers Erwin L.

Vor langer Zeit, in einem Paralleluniversum. Eine völlig unrealistische Geschichte – Science-Fiction.

Jede Ähnlichkeit mit lebenden Personen oder Entwicklungsmethoden ist nicht nur nicht beabsichtigt sondern auch ausgeschlossen.

9:58 Uhr

Erwin Lindemann betritt kurz vor Beginn der Kernarbeitszeit leicht überhastet aber voller Elan das Büro. Wieder einmal war die Buslinie aufgrund einer Dauerbaustelle unpünktlich. Nach Ablage seines Jacke fährt er seine zwei Rechner hoch, um das Tagwerk zu beginnen. Merkwürdig, das Hochfahren seines MacOS Rechners mit diversen automatisch startenden Applikationen dauert doch ein ganzes Weilchen. Erwin Lindemann bespricht sich mit dem auch bereits anwesenden Kollegen Hugo B. und sie beschließen gemeinsam, durch Booten von einer Knoppix-DVD das Dateisystems des Macs einer genaueren Prüfung zu unterziehen. Knoppix prüft.

10:15 Uhr

Gerade als Erwin zur Kaffeemaschine strebt beginnt unglücklicherweise das Daily Scrum.

10:30 Uhr

Das Daily Scrum endet glücklicherweise pünktlich. Unglücklicherweise setzt der Productowner & Scrummaster in Personalunion (die Geschichte spielt sich bekanntermaßen in einem Paralleluniversum ab, in dem so etwas möglich ist und nicht mit dem Tode bestraft wird) unter völliger Überschreitung seiner Kompetenzen gleich noch eine Viertelstunde Backlogpflege-Workshop an. Erwin’s Koffeinspiegel sinkt lebensbedrohlich ab.

10:45 Uhr

Nach der gemeinsamen, harmonischen Backlogpflege – Kollege V. hat wieder einmal mit seinen “das braucht maximal 2 Storypoints” Schätzungen geglänzt – strebt Erwin mit stierem Block erneut der Kaffeemaschine zu, um seinen Koffeinspiegel auf ein halbwegs lebenserhaltendes Niveau zu bringen. Leider stürzt diese bei der Zubereitung des Heißgetränkes nach weniger Sekunden mit einer kryptischen Fehlermeldung ab – der Kaffee ist alle. Beim Nachfüllen bemerkt Erwin, daß die Kaffeevorräte insgesamt zur Neige gegangen sind. Er pilgert durch’s Büro, um den Kaffeeverantwortlichen zu finden und diesen auf diesen eklatanten Missstand aufmerksam zu machen. Hugo V., der Kaffeeexperte, berichtet gerade seinem Freund und Kollegen Karl Y., wie er es letzte Nacht im Online-Rollenspiel World of Witchcraft trotz erheblicher Widerstände eines als Mitspieler getarnten amerikanischen NSA-Analysten geschafft hat, auch die letzte Bastion der Unix-Elfen zu erstürmen. Da Erwin auch ein großer Freund von World of Witchcraft ist, klinkt er sich in das Gespräch ein und berichtet begeistert über das letzte Wochenende, als er World of Witchcraft bei einer LAN-Party des Karnevalsvereins in der örtlichen Mehrzweckhalle installierte. Alle Gesprächsteilnehmer sind sich nach eingehender Diskussion einig, daß aufgrund der Performance-Vorteile nur Ubuntu das Betriebssystem der Wahl sein könne, obwohl natürlich auch Gentoo wegen der aktuelleren Sicherheitsupdates in die engere Wahl gezogen werden müsse.

11:00 Uhr

Mit einer nun vollen Kaffeetasse bewaffnet kehrt Erwin voller Tatendrang an seinen Rechner zurück. Seine Story wurde beim Sprint Planning mit genügend Zeit beschätzt und er brennt darauf, die Story zu erledigen. Er läßt erst einmal einen svn update (die Geschichte spielt bekanntermaßen vor langer Zeit) und einen kompletten Build des gesamten Systems laufen, um auf den neuesten Stand des Quellcodes zu kommen. Sicher ist sicher. Eine solide Basis für den Tag.

Der Build dauert ein paar Sekunden und Erwin wirft einen Blick auf seinen Mac – Knoppix meldet keine Beschädigungen auf der Bootplatte. Nochmal den ausgewiesenen Experten Hugo B. kontaktiert. Dieser kratzt sich ausgiebig am Kopf und wirft die Frage auf, ob Erwin nicht mit einer SSD als Bootplatte besser bedient wäre. Eine gute Idee, denkt Erwin, und schaut gleich mal bei arlt.de nach den aktuellen Preisen. Arlt.de bietet eine Sandvox GTI 3000 für 129€ oder eine Alligator Vertex 2 für 149€ an, beide erscheinen ihm als geeignete Kandidaten. Erwin ist sich allerdings ob der angegeben Firmwareversionen unsicher und prüft auf dem bekannten Forum technik-freaks.de, ob bereits Erfahrungswerte mit dieser Firmware vorliegen. Siehe da, diverse Forumsmitglieder widersprechen dem detaillierten Testbericht der Alligator Vertex 2 und berichten von enormen Performance-Einbußen im Nanosekundenbereich bei Schreiboperationen für große Mengen von Dateien mit weniger als 0.5KB Größe. Der Experte Hugo B. ist sich nicht sicher, ob das Formusmitglied nicht “Nano” mit “Mikro” verwechselt hat und empfiehlt, nochmals beim konkurrierenden Forum hardware-für-dummies.de vorbeizuschauen. Aber die dort zahlreich vorgetragenen Argumente überzeugen Erwin nicht. Er entscheidet sich nach reiflicher Überlegung dafür, bei nächster Gelegenheit eine Sandvox GTI 3000 vorzuschlagen.

12:00 Uhr

Ein Blick in seinen Mailer offenbart Erwin, daß die Builds mal wieder nicht durchgelaufen sind. Naja, einer muß sich ja zuständig fühlen. Eine genauere Analyse zeigt, daß die periodisch erscheinenden Updatemeldungen des Betriebssystems das Buildscript zum Abbrechen bewogen haben. Gründlich wie er ist, installiert Erwin die neuesten Patches auf allen 4 Buildrechnern und startet die Builds erneut. Leider bricht der Build nun sofort mit kryptischen Fehlermeldungen ab. Eine Befragen von google.de und das Durchforsten diverser Foren ergibt, daß die im Buildsystem verwendete Version der Scriptsprache nicht mehr mit dem letzten Betriebssystem-Patch kompatibel ist. Erwin lädt seufzend die aktuellen Sourcen und übersetzt die Laufzeitumgebung der Scriptsprache neu. Endlich, die Buildscripts starten wieder. Daumen drücken.

13:00 Uhr

Mailer schließen und kurz in die Entwicklungsumgebung geschaut. Das am Vormittag gestartete svn update & der komplette Build brauchten wohl keine 5 Minuten. Ein Glück, daß Erwin bevorzugt auf einem Windows-Rechner arbeitet, auf dem solche kurzen Turnaround-Zeiten die Regel sind.

Leider ist das Frühstück heute morgen ausgefallen, es meldet sich ein Hungergefühl. Erwin bereitet sich in der Küche ein Mittagessen zu. Gerade die Kombination von Rohkost mit Quark ist wegen der fettlöslichen Vitamine für ein effizientes Arbeiten unerlässlich. Während er sein verdientes Mittagessen vor seinem Rechner zu sich nimmt, informiert Erwin sich auf heise.de über die neuesten Nachrichten aus dem IT-Sektor. Unglaublich, Roland Profalla von der CDU fordert eine Internetsperre für alle über 18-jährigen, damit der aktuellen Abhöraffäre um das Handy seiner Scheffin wirkungsvoll begegnet werden könne. Noch unglaublicher, was für inkompetente Kommentare andere Leser zu diesem Artikel abgeben. Erwin beschließt, diesen Internet-Trollen mit einem wohlformulierten Forumseintrag ein für alle Mal zu zeigen, wo der Hammer hängt.

13:30 Uhr

Erwin räumt sein Geschirr vorschriftsmässig in die Küche. Die Nahrungsaufnahme und der Anblick der Toilettentüre haben Erwin’s Verdauung in die Gänge gebracht. Er verschwindet auf der Toilette und liest den zufälligerweise in der neuesten c’t enthaltenen mehrseitigen Testbericht zu SSDs, der ihm allerdings auch bei genauestem Studium keine neuen Erkenntnisse bringt.

13:50 Uhr

Tatendurstig erscheint Erwin wieder aus den Niederungen seiner Verrichtung. Als er am Scrum-Raum vorbeikommt, sieht Erwin, wie der leicht gestresste Scrum-Master das Board umorganisiert. Hilfsbereit wie er ist, unterstützt Erwin den Scrum-Master, druckt die 100 neuen Kärtchen aus und heftet diese zusammen mit dem Scrum-Master an die Wand. Der Scrum-Master ist wieder entspannt.

14:15 Uhr

Zurück vor seinem Rechner will Erwin gerade tatendurstig mit der Bearbeitung seiner Story starten, als sich zwischen zwei Kollegen eine technische Diskussion um die Implementierung eines anderen Tasks entspinnt. Da die beiden Kollegen nicht wirklich weiterkommen, abgesehen sowieso eine gewisse Planlosigkeit bei generischer Programmierung offenbaren und zuguterletzt auch Erwin tangential betroffen ist, schaltet er sich in die Diskussion ein. Diese driftet kurz darauf in theoretische Spekulationen über mögliche Performance-Implikationen völlig unbekannter und nie geahnter Implementierungsvarianten ab. Da es schon 14:50 Uhr ist, entscheidet die Runde auf den Scheff zu warten, der jede Minute eintrudeln sollte, um diesem eine Entscheidung abzuringen.

15:00 Uhr

Der Scheff betritt gehetzt das Büro und wird von der immer noch beieinander sitzenden Runde sofort kassiert.

15:10 Uhr

Der Scheff hat wie nicht anders zu erwarten auch keinen Plan (auch in Paralleluniversen vor langer Zeit ein weitverbreitetes Phänomen) und flüchtet sich in Allgemeinplätze wie “Da ist was falsch” oder “Das müßt Ihr anders machen”. Nach kurzem Nachdenken trumpft er dann mit einem “Was sagt denn eigentlich der Debugger? Schon mal reingeschaut?” auf. Verdammt – daran hatte natürlich niemand gedacht. Die Runde entscheidet sich, das Thema erst genauer am Rechner zu analysieren bevor man weiterdiskutiert. Als ausgewiesener ÖPNV-Jünger macht Erwin L. den Scheff noch dankenswerterweise darauf aufmerksam, daß die aktuelle Webcam für die Umgehungsstraße einen Bautrupp zeigt, der seit 11:00 Uhr gerade beide Fahrbahnen aufreißt und offensichtlich seit 2h nicht in die Pötte kommt, weil die Biervorräte zur Neige gegangen sind. Ein Ende wäre nicht abzusehen, da der örtliche Bioladen aufgrund eines Lieferengpasses aus Oberbayern kurzfristig auch keine Starkbiervarianten mehr anbieten könne. Der Scheff möge bei der späteren Heimfahrt vorsichtig sein.

15:15 Uhr

Erwin wendet sich wieder seinem Rechner zu. Wo war er stehen geblieben? Ah, seine Story. Genau. Noch schnell ein svn update – man ist ja paranoid – und Erwin beginnt mit der Bearbeitung. Erstaunlich – ein Kollege, der vor ihm am fraglichen Teilsystem arbeitete, hat bereits Tests für die fragliche Klasse entwickelt, obwohl aufgrund der externen Abhängigkeiten zu einer SQL-Datenbank sowie einem Regensensor eigentlich eine testgetriebene Entwicklung von vorneherein ausgeschlossen scheint. Erwin startet also seinen Tag mit dem Erstellen eines Tests für seine neue Funktion. Was könnte man denn testen? Hmm. Ah. CHECK(container.size() == 0);

15:20 Uhr

Noch schnell den neuesten Codestand aus dem svn besorgt und Erwin startet erwartungsvoll den Build, um den Code für seinen Test auszuprobieren. Oha, das Übersetzen dauert wohl mehr als fünf Sekunden, da hatte jemand doch noch eine größere Menge Code in der Zwischenzeit… Erwin beschließt, nicht auf das Ende des Übersetzungsvorgangs zu warten und wendet sich wieder seinem Browser zu. Oha, da ist ja noch der Reiter mit dem heise.de Forums-Thread zu Roland Profalla offen. Unfassbar, schon wieder über 30 Einträge aufgelaufen. Komplett planlos, diese Leute von der CDU. Und zuviel Zeit haben sie auch noch. Erwin beschließt seufzend, noch einen letzten Versuch zu starten und schreibt den Trollen nochmal sehr deutlich was er von ihnen und insbesondere der Heldenverehrung des Franz Josef Strauß in der bayrischen Geschmacksrichtung der CDU hält.

15:35 Uhr

Befriedigt wendet sich Erwin wieder seiner Entwicklungsumgebung zu. Der Build war inzwischen erfolgreich und dauerte nur 30sec – Erwin nutzt schließlich einen schnellen Rechner der neuesten Generation. Erwin ist begeistert, der Code für seinen ersten Test läuft auf Anhieb. Er schreibt einen weiteren Test, der schon eine etwas anspruchsvollere Lösung erfordert. Erwin bittet daher zwei andere Kollegen, die seit mehreren Minuten enthusiasmiert den gestrigen Champions-League Abend auf Sky Revue passieren lassen, ihr Gespräch im Besprechungszimmer fortzusetzen – er müsse sich konzentrieren. Abgesehen davon wäre er der Meinung, daß das von Jürgen Klopp favorisierte 4:2:3:1 System gerade gegen stärkere Mannschaften aus dem ehemaligen Ostblock zu gefährlich sei, weil aufgrund der fehlenden Überzahlsituation an der vorderen rechten Eckfahne Konter über die Außen nur sehr eingeschränkt abgefangen werden könnten. Der aktuelle Aushilfsstürmer sei auch ein reiner Strafraumspieler, der weder in der Arbeit nach hinten entsprechende Akzente setzen könne noch wisse, wo das Tor steht. Die Kollegen widersprechen selbstredend, verziehen sich aber nach längerer, erhitzter Diskussion unter Murren ins Besprechungszimmer.

16:20 Uhr

Nach 30min intensiven Nachdenkens immer noch keine Lösung für den Test gefunden. Erwin beschließt sein Gehirn durchzulüften, den Kollegen das Auffrischen der Kaffeevorräte abzunehmen und pilgert zum Kaffeeröster des Vertrauens. Glücklicherweise war der Kaffee im Angebot. Echte Arabicabohnen mit erhöhtem Koffeingehalt. Das Sprintziel erscheint erreichbar.

16:40 Uhr

Wieder zurück im Büro, wird Erwin vom Kollegen Q. abgefangen, der mit deprimierter Stimme von Abstürzen mit dem neuesten Build auf seiner Maschine berichtet. Erwin hört sich die Sorgen & Nöte geduldig & aufmerksam an, richtet Q. mit seiner bekannt optimistischen Art wieder auf und man verabredet sich auf den morgigen Vormittag, um gemeinsam das Problem zu analysieren.

16:55 Uhr

Wieder zurück an seinem Rechner ist die algorithmische Lösung schnell gefunden. Der zweite Test läuft. Saubere Sache. Es geht voran. Weiter im Text. Dritter Test.

17:15 Uhr

Aufgrund der kalten Witterung bietet sich Kollege Y. an, eine Runde Eis für die Mannschaft zu holen. Eine leckere Sache. Erwin erbittet zwei Kugeln Vanille aus biologischem Anbau sowie eine Kugel Schlumpfeis.

17:30 Uhr

Nach dem gemeinsamen, den Zusammenhalt des Teams stärkenden Verzehr des Speiseeises geht Erwin wieder an’s Werk. Er findet nach kurzem Suchen ein Stück Code, welches mit ein klein wenig Arbeit auch seinen vierten Test erledigen könnte. Aufgrund der fortgeschrittenen Stunde kopiert Erwin dieses Codefragment kurzerhand in seine Funktion, ein paar kleine Änderungen und siehe da, auch der dritte Test des Tages läuft erfolgreich durch. Erwin kommt in Schwung.

18:15 Uhr

Die kostenlose Time-Tracking Applikation seines Smartphones informiert Erwin darüber, daß er heute schon über 8h 15min Büro weilt. Er beschließt den Tag, indem er seine Arbeitszeit am JIRA Task logged: 2.5h (in diesem fiktiven Paralleluniversum wird Timetracking scheinbar zur Selbstkontrolle verwendet). Hmm, damit hat er die für diesen Task veranschlagte Zeit bereits um 1.5h überzogen. Und Erwin hat noch einige andere, komplexe Stories in diesem Sprint zu meistern, von den eingegangenen Code Reviews für bereits erledigte Tasks einmal ganz abgesehen. Das Sprintziel scheint gefährdet. Erwin notiert sich, dass er dies beim morgigen Daily Scrum zur Sprache bringen muss. Bei der nächsten Retrospektive muss er darauf drängen, dass die Zeiten für die einzelnen Stories & Tasks noch konservativer geschätzt und Stories vorab genauer analysiert und besprochen werden.

18:20 Uhr

Erwin Lindemann beschließt sein Tagewerk und strebt seinem heimischen Rechner zu, um endlich einmal produktiv eine neue Version von Debian aufzusetzen.

Wie erwähnt – die Geschichte spielt in einem Paralleluniversum. Vor langer Zeit. Völlig unrealistisch – Science-Fiction.

Jede Ähnlichkeit mit lebenden Personen oder Entwicklungsmethoden ist nicht beabsichtigt und definitiv ausgeschlossen.


08
Aug 13

A few brief thoughts on “Dysfunctional Programming”

Here are a few random thoughts on @SamirTalwar‘s post “Dysfunctional Programming” – learning functional programming in your favourite language (go read it now, I’ll wait for you).

This is an excellent technique to understand the underlying concepts of a new programming “paradigm”. Because the new “paradigm” (*) is not about the language per se, it’s about a new way of thinking about problems, code & potential solutions. A new paradigm presents a new set of constraints and opportunities to the developer. Most of the time, the constraints are pretty easy to emulate (as Samir describes eloquently), sometimes they just require discipline. Plus, you can take advantage of these new opportunities by emulating them in your language of choice (e.g. starting to emulate polymorphism with function pointers in plain C or, as Samir showed, implementing a map function for an immutable list class) (**).

A great session at SoCraTes 2013, I enjoyed it a lot, and will pass this on in an internal workshop at extragroup GmbH.

(*) Most likely, the paradigm isn’t new per se (witness the latest “hype” – functional programming) – it’s just new to you – or, if you’re old enough, you’ve accumulated so much crap in your head that you purged your knowledge about the paradigm over the years anyway.

(**) I have fond memories of moving from structured programming to oo programming way back when using a Burroughs B20 with Pascal (yes, this was considered a leading edge language at that time). Talk about an old dog.


23
Mar 13

Achievement unlocked: iOS Programming – The Big Nerd Ranch Guide 3rd Edition

Achievement unlocked: Despite being a busy father of three and having a day job I pour a lot of energy into, I finally managed to spend countless nights to work through @AaronHillegass’ and @joeconwaybnr’s excellent “iOS – The Big Nerd Ranch Guide 3rd Edition” (and the countless challenges presented therein). I attribute this to a) my generous intake of Monster Energy drinks late at night and b) the compelling way the material is presented.

The book is at it’s best when the authors take the reader through a series of chapters developing what at least remotely resembles a real-life application introducing new concepts along the way, like MapKit, UITableViews, UISplitViewControllers, UIGestureRecognizers or accessing Web services.

I especially appreciated the bottom-up approach of not using template applications to get up-to-speed quickly but starting from scratch instead which helps tremendously practicing basics over and over again.

The weaker parts of the book are those not dealing with “real-life applications” like the chapters on Core Graphics and Core Animation. Although those explain the technology in reasonable detail, they lack the motivation and “connection” of how to use those technology in a “useful” application.

A very minor complaint – The naming of variables is not very consistent across different chapters, I suggest either sticking with abbreviations or going with fully spelled variable names. (*)

But who am I to complain, I barely managed to cough up the hours every night to actually work through the book.

I learned a ton. Strongly recommended.

Off to creating my first iPhone app (you read it here first)…

(*) Run & hide, a nit-picker 😉


15
Feb 13

Uncle Bob Martin @ Objektforum Karlsruhe

On Feb 6, Robert C. Martin (“Uncle Bob”) gave a talk on “Automated Acceptance Testing: Expressing Requirements as Tests” @ ObjektForum Karlsruhe.

A few statements I found worthwhile for future reference:

  • Deployment is a business decision
  • Agile is not about getting more done, it’s about getting bad news early
  • Don’t let the tool dominate you
  • Not a lot of fixture code to write (to enable automated acceptance testing)
  • Test one thing only once

Here’s a thought which struck me while Uncle Bob waxed eloquently about Fitnesse and showed the DSL he created for testing Fitnesse:

A textual representation of a program’s or component’s output is the major prerequisite for automated acceptance testability. If you struggle with automated acceptance tests – as we do (CAD system with rich user interactions and complex objects being generated, dealing with complex object lifetime issues – “this can’t be tested automatically”) – focus on generating a simple textual representation of the results & interactions etc. This is the foundation of automated acceptance testability. It will be way easier to think about automated acceptance testing once you have this foundation in place.

Thanks to Robert for giving an energized talk despite being attacked by a flu virus and to andrena objects ag for organizing the ObjektForum event series.


06
Nov 12

Chaining Setters in C++ (Builder Pattern)

I have seen chaining of setters (in the context of builder pattern implementations) quite a few times in Java code recently, so I thought I jot down a quick C++ version for future reference (tried to get everything in one class for brevity purposes). No rocket science to be seen here, folks, but still a nice technique for creating objects (*):

class Pizza {

private:
	
	class PizzaProperties {
		
	private:
		
		PizzaProperties() : fSize(0), 
							fWithCheese(false), 
							fWithPepperoni(false),
							fWithBacon(false) {
		}
		
		int fSize;
		
		bool fWithCheese;
		bool fWithPepperoni;
		bool fWithBacon;
		
		friend class Pizza;
		friend class PizzaBuilder;
	};
	
	
public:
	
	class PizzaBuilder {
		
	public:
		
		PizzaBuilder(int size)  {
			fProperties.fSize = size;
		}
		
		PizzaBuilder& WithCheese() {
			fProperties.fWithCheese = true;
			return *this;
		}
		
		PizzaBuilder& WithPepperoni() {
			fProperties.fWithPepperoni = true;
			return *this;
		}
		
		PizzaBuilder& WithBacon() {
			fProperties.fWithBacon = true;
			return *this;
		}
		
		Pizza Build() {
			return Pizza(fProperties);
		}
		
	private:
		
		PizzaProperties fProperties;
	};
	
	
private:
	
	Pizza(const PizzaProperties& properties) : fProperties(properties) {
	}
	
	PizzaProperties fProperties;
};

So it’s quite convenient to build up different Pizza objects just by chaining the different “setters” – no need for default parameters, dealing with constructor bloat (# of parameters and # of constructors) etc. Plus, it’s quite efficient because the “setters” return a reference to a Pizza only, no memory allocation needed.


	Pizza largeMargheritaPizza = 
		Pizza::PizzaBuilder(30).WithCheese().Build();

	Pizza smallHotPizza = 
		Pizza::PizzaBuilder(20).WithCheese().WithPepperoni().Build();

(*) The code focusses on the chaining aspect of a builder pattern implementation – not the use of different builder objects for creation.


24
Sep 12

Staring is not an efficient coding technique

The following quote from Buzz Andersen’s blog (which I highly recommend) caught my eye:

…full-time pairing can make the certain amount of “staring into space” time every programmer needs to get things right excruciatingly awkward.

I don’t want to dive into the pair programming discussion this time, I’ll leave this for another post. I would like to talk about staring. Staring on the code. Staring on a comment. Staring on a UML design sketch. Or, as Buzz puts it, staring into space. (*)

As far as I can tell (and I have done my fair share of staring over the years), staring is a software engineering technique where, for an extend period of time, the software developer refrains from any movement of his extremities, stops moving his eyeballs and focusses on a particular piece of code, while his CPU cores, umm, brain runs at 100% load trying to solve the problem at hand.

If we’re lucky, said developer appears to wake up from time to time, types a few characters, maybe adds a comment and resumes staring. If we’re less lucky, said developer will remain unresponsive for extended amounts of time and will make no measurable progress towards his goal.

I don’t dispute that “Staring” may be a technique to get things right, but I would like to go on the record that it’s an efficient technique to get things right. Day after day, I observe that developers “stare into space” or, even more inefficient, “stare on the code” in order to solve problems. However, I’ve never seen a problem getting solved by staring, I’ve only seen problems getting solved by adding or changing code.

Why is staring an inefficient technique, you may ask?

Staring is inefficient because it doesn’t employ a feedback loop. You are reasoning about the code with yourself. Nothing wrong with it, but there’s no one involved giving you feedback on your thoughts or challenging your assumptions – after all, it’s just you staring at the code.

If you catch yourself staring at code too often, make sure to get into the habit of doing something with the code instead:

  • Even if you don’t have automated tests (and you know you should, don’t you), you can do tiny, lowest-risk refactorings which help you deepen your understanding of the code just a tiny little bit. Rename a variable, a function, extract a few lines of code to a new method, write a comment (gasp), change the formatting to suit your style (quadruple gasp). You can always revert this changes after you understood what’s going on (you do use version control, don’t you?)
  • How about running the code in a debugger to get the additional feedback of variable / objects / state changes at runtime?
  • How about writing unit tests? Write a test, write a little bit of code, write some more code, see a test failing, change the code, write a test to test your assumptions about specific parts of the code. Do a change to the codebase to learn something? Do the tests still run? Great. They don’t? Looks like your assumptions were wrong. Trace back, take another route.

If you absolutely must “stare” at the code, I suggest to take a step back and “sleep on it” or to take a short walk. But those are techniques which should be reserved to occasions when you really got stuck and you’re trying to solve really hard problems. Guess what, most of the time the problems aren’t that hard. They may be challenging but they are quite solvable by taking tiny, reproducible (sometimes revertible) steps towards a solution.

Code is like clay. Make sure to mold it. Carefully. You’ll learn way more by molding the code, not by staring at it.

(*) Don’t want to get into discussing “staring on web-sites not at all related to the task at hand” either.


23
May 12

Softwerkskammer Karlsruhe, 9th Meeting

This time, we decided to do the widely known Roman Calculator Kata. Coding via a beamer worked surprisingly well, especially after Nicole took over who’s a way faster & smarter typist than yours truly.

A couple of observations:

  • Although we started doing TDD (with the proper focus on “Driven”), the group quickly moved away from “doing the simplest thing that could possibly work” and started putting out new algorithmic variants of the solution at an amazing rate using the existing tests as a safety net
  • Taking small steps is a challenge if you’re in a room with smart people who tend to solve the problem right away by applying their superior brains
  • Taking baby steps is even harder in such a setting
  • It would be an interesting exercise to clean up the code produced as much as possible (and making it as C or C++ like as possible while doing so)
  • It would be an interesting exercise to start over with a clean slate and try a different order of the tests and see how this effects the algorithm chosen
  • Another variant would be to start with or at least add tests which check for edge cases or error conditions
  • Note to self: More cold soft drinks are needed / programmer food would be nice, too

A great, educational way to spend the evening. Thanks to all the participants – I look forward to the next meeting.


27
Apr 12

The main benefits of TDD

For me, there are two main, long-term benefits of TDD (Test-Driven Development):

First, by using TDD (thus writing the tests first) you make sure that your code remains in a testable state all the time (even if you don’t write all the tests to cover all the edge cases) – As anybody working with legacy code can attest, adding unit tests to an existing code base is usually excruciatingly hard and takes a lot of time. It can be done – witness Working with Legacy Code, sure, but it’s a very long and thorny journey. You don’t want to go down this road with the new code you’re writing every day.

Second, by using TDD you always have a decent, highly decoupled design – not a perfect or insanely great design, but quite a usable design to go forward. More often than not, it will be a better design than you’re used to.

“Test-Driven Development” is actually “Test-Driven Design”.


17
Apr 12

Where does “thinking” and “design” fit into the TDD picture?

I very much enjoyed @unclebobmartin‘s generous talk at the Java User Group Karlsruhe last night. In addition to covering rockets, linear accelerators and small nuclear bombs as a means to overcome the gravitational field of the earth, he gave a great introductory talk on TDD and professionalism. Always a pleasure to be reminded on why we are doing TDD in the first place.

One of the questions which came up during Q&A – I’m paraphrasing here – was:

“I tried TDD and was told not to design or think, just to write the tests and the code. The result was a mess”.

Bob Martin’s answer was along these lines:

If you’re a TDD newbie, you need to leave your old rationale of thinking things through upfront behind. So the recommendation is “Don’t think about the design or what’s next”, but to methodically follow the mantra “Write some failing test” – “Write some code just so the test is satisfied” – “Write some failing test” – “Write some code just so the test is satisfied” – …. As your start to grok the rhythm of TDD, you gradually let your design skills in.

I would like to humbly elaborate on this answer. The practice of TDD consists of three simple steps:

  • Step 1 – “Red” – Write some failing test
  • Step 2 – “Green” – Write some code just so the test is satisfied (implement the simplest thing that could possibly work (not sure who coined the term, probably Ward Cunningham))
  • Step 3 – “Refactor” – Remove all duplication from both your production and your test code

Resist your urge to design upfront, to think through algorithmic solutions and alternatives. Just write a failing test. Then, write some code to make the test pass. Don’t write more code. Just the amount of code to make the test pass.

Now, turn to step 3. If you skip it, you will create a mess.

Step 3 is where your design skills are more than welcome. Apply your design skills to ruthlessly eliminate the duplication you created (and you did create some duplication because you did “the simplest thing that could possibly work” in step 2, didn’t you?) – Just keep in mind that you are not supposed to create a design which anticipates future requirement changes, you are supposed to ruthlessly eliminate duplication to create “the simplest design that could possibly work” for your current code base.

So there are a lot of design skills involved in TDD. It’s just that most of the design skills are applied “after the fact”. They are applied after you made the failing test pass.

There’s another place for design skills in TDD. Look at the first step – “Red”. You are supposed to write a failing test. You will probably need to instantiate an object (which, keep in mind, doesn’t exist yet). Or call a function or method (which don’t exist yet, either) on an existing object. You can apply your API design skills right there: What’s the best way to name the class or function? Which parameters do you need? How do you minimize the number of parameters? How do you make it easy for the test (and future users of the class / function) to accomplish the task at hand?

You aren’t convinced yet? You still need more places to apply your superior brain powers? Good news, there’s even more “thinking” involved. In step 1, you are supposed to write a failing test. This requires a lot of thinking:

  • What do I test next?
  • What’s the next logical step in the evolution of my method / class?
  • What are the edge cases I need to test for?
  • Which test will small enough in scope that I can cope with the implementation right away?
  • Which test will bring me closer to the solution of the task i’m working on?

Conclusion

If you follow TDD and apply your thinking and design skills as described above, you will end up with a testable, highly decoupled design. It’s not a great design yet, but chances are it’ll be a much better and more usable design than the ones you’ve encountered so far.

Addendum

You may wonder why I didn’t mention the long and hard thoughts you need to think in step 2 while writing the code to make the test pass. Two questions for you: You did write some failing test, just enough testing code so the test fails, correct? Then you did the simplest thing that could possibly work to make the test pass, correct? Nothing more? Good. Go figure.


29
Feb 12

Softwerkskammer Karlsruhe, 6th Meeting

Finally, I managed to attend a meeting of the Softwerkskammer Karlsruhe, a group of software professionals dedicated to improving their craft. Todays topic was Flow Design and Event Based Components, a presentation graciously provided by Tilmann Kuhn. He gave a short overview of Flow Design and then dove into a sample implementation using Event Based Components in Java (a language I used to be more familiar with in the 90s). Java’s (and the associated frameworks’) verboseness aside, flow design and its implementation very much reminded me of Prograph CPX, a graphical data flow language of the early 90s. In order to close the daunting gap between the flow design’s graphical representation and its textual implementation an integrated IDE is (IMHO) essential.

Then, Hayati Ayguen presented his take of a flow implementation in C++ for signal processing. Terse. Brief. Very focussed on a specific use case – Signal processing. Just enough infrastructure to make it work efficiently. A wonderful contrast to the Java implementation – which does have its merits, don’t get me wrong.

A great and thought provoking evening. Thanks to the organizers. I look forward to participate in upcoming meetings.

[Update 3/2/12 – Fixed up an incomplete sentence – Looks like it was way to late Wednesday night (or I got distracted by the late night soccer game analysis on TV ;-)]