22 July 2013

Corey's Pair Programming Tour

After my last rant on the missing quality in today's mainstream IT I got several mails from friends who had heard that I had quit my job (for the same reason). They asked me what I was up to now? The short answer is that I am planning a Pair Programming Tour (called Code Cop Tour). The long answer needs more explanation.

The Beginning
Like in every good story, let us start at the beginning - well maybe not at the very beginning, but let us start with Corey Haines. In 2008 Corey Haines, an US based programmer, lost his job and embarked on an unique, personal "Pair Programming Tour" around central US. He was travelling around, practising software development, pair-programming with people for room and board (room and food). InfoQ posted a summary about his first trip back in 2008, that I will in part repeat here: ... Corey Haines has embarked on a tour in the name of increasing our industry's emphasis on software as a craft. ... While he has dubbed the tour a "Pair Programming Tour", its ultimate intent is somewhat less about the practice of pair programming per se than it is about the ideas of what it takes for a software developer to really become good at what he or she does. ... Haines has posted video interviews revealing many of the unique insights he has gained about pairing, automated testing, and the evolution of a software craftsman while sharing the keyboard at the home-bases of Dave Chelimsky, Brian Marick, Uncle Bob Martin, and others.

Journeyman at WorkCorey maintained a blog On Being A Journeyman Software Developer throughout his travels where he recorded his insights. While preparing for my own tour, I read it all, right from the first entry. Here is my summary:

Several Trips
Corey spent an entire year being a Journeyman Coder. A few others have done similar trips, but much shorter. These trips have been called "Pair Programming Tour", "Journeyman Tour", "Software Craftsman Road Trip", "Software Craftsmanship Walz" and so on. He split his journey into short tours of up to four weeks, using a conference or another event as leg for a trip.

For a certain trip he picked a region to explore, reached out to people that he knew in that region and talked to companies in the area, looking for places to allow him to visit. He knew a lot of people who worked from home, independents and remote workers, who he might visit. He prepared a list of places up front, with 50% already filled with people to pair or companies that would host him. For the remaining time he maintained a Pairing Calendar, that people interested in hosting him could look at.

Pair Programming
In general he spent between one and five days with people, usually two or three days, pair-programming on whatever they wanted to work on. He worked with people of widely varying experience and skill level on various projects. Due to the high density of well known individuals in his area he was also able to work with book authors, open source project leads and celebrities like Uncle Bob. He saw many aspects of software development, gained exposure to new software tools, learned new coding tricks and thus both actively trained others and got trained himself. (Pair Programming is next to many things a powerful technique for sharing knowledge.)

When visiting companies (I assume) he was just another member of the team and contributed as much as possible. Still he was an outsider with his own views and experiences, who most likely acted as agitator as well. (Obtiva's Jake Scruggs explained the role of agitator in his report about the 8th Light vs. Obtiva Craftsman Swap: The workers all believe the same, so they do not have a hard object to push up against. They got to sharpen their edges on me, and I got to sharpen my edges on them.)

Reflection during Travel
Between pairing sessions Corey drove around the country. He used the long road trips to think about what he had learned and reflect about conversations. He said himself that My head was so full of thoughts after the intense discussions with people; I just had to stop and record my very first "road thoughts." Maybe not by his planning, but this was an important part of a learning tour. To emphasize learning, we need to revisit the material studied before, reflect on it, sort it out.

Teaching
To Corey teaching was as important as learning. He updated his blog regularly, discussed new ideas or revisited old concepts. Next to recording his road thoughts he made several video interviews with people he had paired with. He talked at conferences and spoke at user groups on his way. Later he travelled around and organized Code Retreats in various places. He convinced people that software is a craft and explained the idea of Software Craftsmanship in general.

This is my understanding of the "classic" Journeyman Tour - and exactly this is what I will do. I am planning my tour since two months and in the next blog post I will describe my Code Cop Tour. Stay tuned ;-)

16 July 2013

Word Wrap Kata revisited

Last year in November, my old post about Word Wrap Kata variants suddenly got a lot of visits. Claus told me that well known German blogger Ralf Westphal had linked to it from one of his own articles about Test Driven Development. By using examples from Coding Dojos he explained that using Test Driven Development alone is not enough to get clean code. During the Dojo the participants focused only on the red and green bars and other concerns like design or code readability were neglected. He used my code as examples of solutions got by such a behaviour. While it made me unhappy to serve as negative example, I had to agree with Ralf. When I performed the katas two years ago I explored different algorithms and did not use them to practice TDD. My solutions were technical, instead of reflecting the problem domain.

Try Harder in Your New DreamWhen I attended a Coding Dojo afterwards I paid close attention and was sad to see he that all Ralf's concerns came true. The group did not even understand the requirements completely, when people already started proposing language features and libraries which would solve the problem quickly. Solve which problem quickly? We should think about the problem first and then create code driven by our tests that is clean, readable and open for future change. Ralf had some ideas how to improve these issues behind programming. Obviously code needs to have many qualities beyond its simple correctness.

So I tried again. I got help from my friend Thomas Sundberg and we worked five remote pairing sessions on the Word Wrap code kata. We performed the kata in the "usual" way, without much thought up front and being driven by our tests. Similar to a Coderetreat, we chose additional constraints: We focused on business related names, SRP and Tell, don't ask. As a kata is a learning exercise, we took everything to the extreme. We literally spent hours discussing if a particular name was reflecting the problem domain, renaming it three times or more until we were satisfied. And we spent at least six pomodoros entirely on refactoring and cleaning up. Probably we could still improve it but we grew tired of the exercise and switched to another kata.

When I see the code now, it looks a bit weird, likely because taking "Tell, don't ask" to the extreme means never asking for any state. So the first thing we need is a class that receives the wrapped output, as we cannot ask for it. Word Wrap is an algorithm inside a word processor when a paragraph of text, which does not contain any newlines, is rendered to a page where it needs to be broken into lines of proper length:
interface Page {
    void renderLine(String lineOfProperLength);
}
In breaking the paragraph into lines of proper length, we see several responsibilities: splitting the paragraph,
interface ParagraphSplitter {
    void wrap(String paragraph);
}
which breaks the stream of text down into words, accumulating the words into lines of proper length,
interface LineAccumulator {
    void addAndHyphenateIfNeeded(String word);
    void addWithoutHyphenation(String part);
    void addCarriageReturn();
}
and maybe a hyphenation rule to determine if a word which is too long can be broken into shorter pieces,
interface HyphenationRule {
    void doHyphenate(String word, LineAccumulator lineAccumulator);
}
We did not start with this design but arrived at it when removing duplication and multiple responsibilities mercilessly ;-) The obvious implementation of ParagraphSplitter is to split on each blank, e.g.
class SeparateWordsOnBlanks implements ParagraphSplitter {

    private final LineAccumulator accumulator;

    // constructor omitted

    public void wrap(String paragraph) {
        for (String word : paragraph.split(BLANK)) {
            accumulator.addAndHyphenateIfNeeded(word);
        }
        accumulator.addCarriageReturn();
    }
}
which is not exciting at all. The heavy lifting is done by the accumulator which checks if adding the current word would exceed the maximum line length, invokes the hyphenation and adds blanks where needed. Whenever a line is complete it is rendered to the page.
class LineLengthAccumulator implements LineAccumulator {

    private final Page page;
    private final HyphenationRule hyphenation;
    private final int maximumLineLength;
    private StringBuilder currentLine = new StringBuilder();

    // constructor omitted

    public void addAndHyphenateIfNeeded(String word) {
        if (exceedingMaximumLineLength(SPACE, word)) {
            hyphenation.doHyphenate(word, this);
            return;
        }
        insertSpaceIfNeeded();
        appendToCurrentLine(word);
    }

    public void addWithoutHyphenation(String part) {
        if (exceedingMaximumLineLength(EMPTY, part)) {
            addCarriageReturn();
        }
        appendToCurrentLine(part);
    }

    private boolean exceedingMaximumLineLength(String separator, String word) {
        return currentLine.length() + separator.length() + word.length() > maximumLineLength;
    }

    public void addCarriageReturn() {
        if (currentLineHasWords()) {
            renderCurrentLine();
            lineFeed();
        }
    }

    // some private methods omitted

}
There are a bunch of unit tests using a NoneHyphenationRule or different anonymous mock rules to drive the functionality of the LineLengthAccumulator. For example
@Test
public void shouldNotWrap() {
    Page mockOutput = mock(Page.class);

    LineAccumulator accumulator = new LineLengthAccumulator(mockOutput, 78);
    accumulator.addAndHyphenateIfNeeded("This");
    accumulator.addAndHyphenateIfNeeded("is");
    accumulator.addCarriageReturn();

    verify(mockOutput).renderLine("This is");
    verify(mockOutput, times(1)).renderLine(anyString());
}
The HyphenationRule needs to know its accumulator and the other way round, which creates a conceptual cycle. Additionally we need a second method addWithoutHyphenation in the LineAccumulator to avoid endless loops during hyphenation. This is the result of following "Tell, don't ask" to the letter. Maybe HyphenationRule would be better off just returning the hyphenated word.
class SplitOnCamelCase implements HyphenationRule {

    public void doHyphenate(String word, LineAccumulator lineAccumulator) {
        if (foundAnUpperCaseLetterIn(word)) {
            String remainingWords = splitFirstSyllableFrom(word, lineAccumulator);
            doHyphenate(remainingWords, lineAccumulator);
        } else {
            lineAccumulator.addWithoutHyphenation(word);
        }
    }

    // private methods omitted
}
To unit test the hyphenation rules, a mock accumulator is used to verify the proper syllables.
@Test
public void shouldHyphenateWords() {
    LineAccumulator mockAccumulator = mock(LineAccumulator.class);
    HyphenationRule strategy = new SplitOnCamelCase();

    strategy.doHyphenate("ShortWord", mockAccumulator);

    InOrder inOrder = inOrder(mockAccumulator);
    inOrder.verify(mockAccumulator).addWithoutHyphenation("Short");
    inOrder.verify(mockAccumulator).addWithoutHyphenation("Word");
    verify(mockAccumulator, times(2)).addWithoutHyphenation(anyString());
}
I am pleased with our result, although it took us too long to complete it, which is a sign how much practice we still need ;-) See its full source code here. You might still find one or another thing that is not optimal and never will be but in comparison with my first version this Word Wrap expresses its problem domain more clearly and is easy to understand even without digging down into all the details.

10 July 2013

Jasmine - Rhino - Ant

Ant on JasmineSome time ago I decided to brush up my poor JavaScript skills. I did not want to use JavaScript to develop web applications but was interested in the language itself. Naturally I started with code katas and little assignments like the ones found at Ruby Quiz. I needed a unit testing framework but during my first steps did not feel like looking for a suitable library and just rolled my own Assert class on top of Rhino which was, at this time, sufficient for me to get things done.

Later when I wanted regular testing during continuous integration, I looked for unit testing frameworks and found Tiest Vilee's RhinoUnit which did the job well. It felt much like JUnit, as implied by its name, and I had no problems using it. After some time I noticed Jasmine being referenced in several presentations and set out to try it. It is a behaviour-driven development framework for testing JavaScript code and does not depend on any other frameworks.

Jasmine and Rhino
Others have successfully ran Jasmine with Rhino using Envjs. (Here is a more detailed description how to do that.) Their intention was to test JavaScript used in web pages without launching a browser by using the simulated browser environment provided by Envjs. As I did not work in a browser environment this approach seemed wrong and I looked for alternatives. David Green used Jasmine on Rhino in his Rescripter, just providing missing global definitions and I worked on top of his code:
(function(global) {

    // timer functions from global for "jasmine.Clock"
    var timer = new java.util.Timer();
    var counter = 1;
    var ids = {};

    global.setTimeout = function(fn, delay) {
        var id = counter;
        counter += 1;
        ids[id] = new JavaAdapter(java.util.TimerTask, { run : fn });
        timer.schedule(ids[id], delay);
        return id;
    };

    ...

})(this);

Standalone Rhino
The version of Rhino shipped with the JDK has been modified by Sun. For example the JavaAdapter has been removed, as written in this document by Oracle. As jasmine-rhino.js (listed above) needs the JavaAdapter to implement a TimerTask, I used the standalone Rhino. To invoke it from javax.script, there must be a ScriptEngineFactory but the standalone Rhino does not provide any. Fortunately I found com.sun.phobos.script.javascript.RhinoScriptEngineFactory on java.net.

Jasmine Reporters
Jasmine uses reporters to report test failures in different formats. Larry Myers offers several useful Jasmine Reporters, e.g. jasmine.console_reporter.js or jasmine.junit_reporter.js which creates XML files suitable for JUnit report generation. These reporters expect an Envjs console and I found myself turning back to Envjs after all. But in the end I created my own console that delegated to the Ant task logger.
Console = function() {
    var logger = {

        error : function(message) {
            self.log(message, 0);
        },

        warn : function(message) {
            self.log(message, 1);
        },

        ...
    };

    return logger;
};
this.console = new Console();
To finally run Jasmine I created a spec runner (AntSpecRunner.js) derived from Jasmine's original SpecRunner.html which started the tests and waited for all of them to finish.
this.execJasmine = function() {
    var jasmineEnv, apiReporter;

    jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 100;

    apiReporter = new jasmine.JsApiReporter();
    jasmineEnv.addReporter(apiReporter);

    jasmineEnv.execute();

    while (!apiReporter.finished) {
        java.lang.Thread.sleep(100);
    }
};

console.log('Jasmine loaded.');

Rhino and Ant
For continuous integration I added Ant support. Now Ant is not the newest nor hottest technology available but I know my way around. Inspired by RhinoUnit I load Jasmine code to execute in Rhino using Ant's Scriptdef task. The script implementation iterates all files of all provided FileSets and calls runTest with each file. Note that self points to Ant's ScriptDefBase task implementation by default.
var testfailed = false;

// helper methods and Ant attributes omitted

var filesets = elements.get("fileset");
for (var j = 0; j < filesets.size(); j += 1) {
    var fileset = filesets.get(j);
    var directoryScanner = fileset.getDirectoryScanner(project);
    var srcFiles = directoryScanner.getIncludedFiles();

    forEachElementOf(srcFiles, function(srcFile) {
        var jsfile = new java.io.File(fileset.getDir(project), srcFile);
        runTest(jsfile);
        if (testfailed && haltOnFirstFailure) {
            self.fail("Jasmine failed.");
        }
    });
}

if (testfailed) {
    self.fail("Jasmine failed.");
}
Each source file, supposed to be a Jasmine spec, is loaded and executed. I created a special Jasmine reporter, jasmine.CountsReporter, to get the number of failed tests back from Jasmine to record failures.
function runTest(file) {
    var failingTests;

    // helper methods omitted

    try {
        Load.file(file);
    } catch (e) {
        erroringTestMessage(file, e);
        testfailed = true;
    }

    failingTests = this.jasmine.getEnv().countsReporter.failingTestNames();
    if (failingTests.length > 0) {
        forEachElementOf(failingTests, function(testName) {
            failingTestMessage(testName);
        });
        testfailed = true;
    }
}
(See the complete integration working here.)

Although I was reusing a lot from rhinoUnitAnt.js and copying from David and others, to integrate Jasmine, Rhino and Ant took me much longer than I had expected. While this might be a general statement about any coding task, I am wondering if I should have went with one of the existing solutions...

7 July 2013

Where is the Quality?

I am professional Java developer since almost 14 years. I have been coding for education, fun and profit for 27 years and three months now. I bought my first book on how to program BASIC for the Commodore 64 in 1986, even before I got the computer itself. I have been enthusiastic about all this since then and never stopped pushing forward. But I am depressed. Maybe I get depressed easily, as once after a particular bad gig I had to take an antidepressant for more than a year. Fortunately no burn-out this time - I am just fed up. Time for a rant ;-)

AngerThe current state of the IT industry makes me unhappy. That is nothing new and maybe my last employer is a particular bad example, but I do not think so. I have been with some companies during my career and talked to developers working on different projects, and usually I hear the same story: Deadline first, crazy rush, get the shit out of the door, repeat. I am the Code Cop, I try to keep things together, clean them up, whip them into shape. But I am wasting my time. My work has no meaning. I am just one but "they" are legion. Recently I got really angry when being confronted with bad code. How do you dare to deliver such crap to my production code base. This is all a big joke.

Some developers have no idea about object orientation, encapsulation or how to design a class at all. The senior developers know their business and applications well, still some of them are unable to create a reasonable design or model classes with a single responsibility. This does not only apply to off-shoring, but to local teams as well. Managers and architects are talking about all aspects of the development cycle but the actual creation of the core asset, the executable code. Development of code is seen as a commodity, unimportant work, just fill in the gaps.

Dark Future
Last month I was invited to a small panel discussion. Together with a test automation expert and an user interface specialist, we were discussing with the audience about the future of software development. The opening question was for our advice for students of higher technical education. Where the testing and user interface people predict a bright future, I have a darker vision. I would not advise anybody who is passionate to start working in today's mainstream IT industry. Software is growing more and more complex and changing it takes longer and longer. At the same time the cost pressure increases. Current trends like Water-Scrum-Fall try to fix these problems with a process. The real issue is the bad quality of our code. We have accumulated a massive amount of technical debt. The same is true for testing. Yes, we plan for unit tests during development, but then need to finish the requirement first and skip the tests. In the end we get some UI test automation, delivered by an outsourced testing team. Hello software testing ice-cream cone.

Dead EndEscape?
I get many mails from head hunters looking for Java developers. But their work is as broken as ours. I am sure, if they would just read one post of my blog they would not send me information about an open position for a junior developer who is supposed to add buttons to a web application. Some head hunters are even specialized in IT personnel but seem to be as (un-)skilled in their work as most of us. From my experience they just do not care, else they would not send me letters with a wrong name in the salutation. Anyway, all advertisements for job vacancies I have seen so far were flat and did not say anything about what to expect. I am not excited.

I believe that the Software Craftsmanship movement was born to address these issues. But Austria is a small country and I am not aware that there are companies like 8th Light around. Still I know of many passionate developers and would like to hear about companies, where all members of the development team are craftsmen. It will definitely be a small company, at least a small development team hiding somewhere. So please stop hiding and come outside, I am looking for you! (I really hope you exist ;-)