Web Apps in TDD, Part 3

Rendering a building

What’s next on the todo list? I want a rectangle to appear on the screen to show a building.
Google tells me there’s a nice javascript library to draw vector graphics on a browser. I think I’ll try it, it’s called Raphael.
So I write an html file using this library to draw a rectangle :


<html>
<head>
    <script type="text/javascript" src="raphael-min.js"></script>
    <script type="text/javascript" charset="utf-8">
        window.onload = function() {
            var map = new Raphael(0,0,600,400);
            var building = map.rect(10,10,50,40);
        };
    </script>
</head>
<body>
</body>
</html>

And with this I get :

A real beauty. The building is the small rectangle top left.

Now I would like my HtmlScreen to return that.

Testing the behavior

I could write a test like this :


    @Test
    public void shouldRenderABuildingAsARectangle() {
        assertThat(new HtmlScreen().render(), is("<html>\n" +
                "<head>\n" +
                "    <script type=\"text/javascript\" src=\"raphael-min.js\"></script>\n" +
                "    <script type=\"text/javascript\" charset=\"utf-8\">\n" +
                "        window.onload = function() {\n" +
                "            var map = new Raphael(0,0,600,400);\n" +
                "            var building = map.rect(10,10,50,40);\n" +
                "        };\n" +
                "    </script>\n" +
                "</head>\n" +
                "<body>\n" +
                "</body>\n" +
                "</html>"));
    }

But it would be awfully fragile. More to the point : it would not declare what I’m interested in.
What is it I’m interested in? If this were a test for some internal functionality it would be easier, you just have to think at what the clients of an object expect from it. Here the client of the rendering from the HtmlScreen is the user : the biped that is looking at the computer screen.

What I would really like to write in my test is :


    @Test
    public void shouldRenderABuildingAsARectangle() throws Exception {
        User user = new User().lookAt(new HtmlScreen().render());
        assertThat(user.currentSight(), is("A Rectangle at [10,10], 40px high and 50px wide"));
    }

Then I think I’ll write exactly this and I’ll find a way to make it work. A solid, meaningful test is definitely worth the effort.

The are three pretty separate issues here :

  • The user should be able to look at the rendering and extract the parts of it which are meaningful for it, right now that means the javascript.
  • The user should be able to evaluate those meaningful parts and get me a short description of the final result.
  • HtmlScreen should return the correct html with the script needed to satisfy the user

Before attacking any of this I put my html inside a string within the test itself and I pass it to the user, I want to make sure that when my user will work I will know.


    @Test
    public void shouldRenderABuildingAsARectangle() throws Exception {
        String html = "<html>" +
                "<head>" +
                "    <script type=\"text/javascript\" src=\"raphael-min.js\"></script>" +
                "    <script type=\"text/javascript\" charset=\"utf-8\">" +
                "        window.load = function() {" +
                "            var map = new Raphael(0,0,600,400);" +
                "            map.rect(10,10,50,40);" +
                "        }" +
                "    </script>" +
                "</head>" +
                "<body>" +
                "</body></html>";
        User user = new User().lookAt(html);
        assertThat(user.currentSight(),
        	is("A Rectangle at [10,10], 50px high and 40px wide"));
    }

Now, on with the implementation of my user.
The first problem is quickly solved, I’ll have the user parse the received html and extract all scripts. The second problem is partially solved by using Rhino to evaluate the scripts.

There’s one thing that hangs : provided I can run the javascript in my user, that javascript does not produce a fancy (and easy to check) text description of what the user sees, it calls Raphael which performs some vector graphics magic.

Luckly, stubbing objects and whole libraries in javascript is trivial. In my tests I’ll replace the Raphael library with this file :


    function Raphael(x, y, width, height){
        this.rect = function(x, y, width, height) {
           output += "A Rectangle at [" + x + "," + y + "], " + height + "px high and " + width + "px wide";
        }
    }
    
    var output = "";

I run this and the test is still red, Rhino says that there’s no window object available. Indeed the window object is provided by the browser. I’ll just make sure that my user executes a browser.js file before everything else when evaluating the HtmlScreen :


    function Window() {}
    var window = new Window();

The test is green.

I move the html to HtmlScreen, this test is green but the old one is red, remember the first test for HtmlScreen?


    @Test
    public void shouldRenderAnHtmlDocument() {
        assertThat(new HtmlScreen().render(), is("<html><body></body></html>"));
    }

That’s definitely not true any longer. Is interpolating the microdivergence between these two tests going to help my design? Maybe, but I’ve added a lot for this last test, I don’t want to follow up with further changes in the production code just to satisfy that old boring test. Moreover, the reason that test is failing is that it is extremely dependent on the actual html string.

That’s not really good, especially since I’ve done so much to avoid being dependent to the html string in my latest test. Finally, I’ve just added a dom library for use inside the user, it’s really quick to change that test to declaring the same thing without being this fragile :


    @Test
    public void shouldRenderAnHtmlDocument() throws Exception {
        Document document = new Builder().build(new HtmlScreen().render(), null);
        Element root = document.getRootElement();
        assertThat(root.getLocalName(), is("html"));
        assertThat(root.getChildElements("body").size(), is(1));
    }

Is it me, or there’s still no really simple xml library for Java? This is xom, I decided to try it after years of jdom, dom4j and the basic java dom (ugh!) : it has a simple builder, good; poor navigation, bad; and it forces me to pass a null in the builder since I have no base url, very bad.

Anyway, the HtmlScreenBehavior tests are all green. I’ve one red test, it’s BossBehavior. It complains that raphael does not exist.
In fact the WebClient performing the http call is parsing the html from the server response and it is calling the server to obtain the raphael-min.js. My server does not currently return static resources.
Even if I have a red test I add a new one into BossBehavior, which is far more focused, that will ensure a clear feedback and also prove my theory on the origin of the error.


    @Test
    public void shouldReturnAStaticFileWhenAPathIsProvided() throws Exception {
        boss = new Boss(PORT, new BlankScreen());
        assertThat(Http.callOn(PORT, "sample.content.txt"),
		is(HttpAnswer.with("foo content bar").type("text/plain")));
    }

Inside the sample.content.txt file I got the string “foo content bar”.

Indeed the test fails, as expected.

Grizzly has a nifty Adapter ready for this, the StaticResourcesAdapter, but, how to choose between my original adapter and this one? Well, when a resource is required I’ll use the StaticResourcesAdapter, when no resource is requested it will be my original adapter.
Doesn’t this sound a lot like mapping?


public class AlwaysReturn{
	...
        public void service(Request request, Response response) throws Exception {
            String path = request.unparsedURI().toString();
            if(path != null && !path.equals("/")) {
                filesRetriever.service(request, response);
            } else {
                HttpAnswer.with(screen.render()).writeTo(response);
            }
        }
        ...
}

The “filesRetriever” is the static resources adapter from Grizzly.

I run all tests and they are all green!

I perform a reality check, I launch Boss with its main and I call it with a browser.

And here it is, the first building of my city.

Yet looking back at the last piece of code I wrote, I don’t like what I see. Simply put, the service method is a mess : it is performing operations from multiple levels of abstraction, it is meddling with the static adapter while it is also performing actions which are specific to the screen. Finally it belongs to a class “AlwaysReturn” whose name has lost all meaning.
I’ll clean this in a pretty direct way, for now.


    private static class RootAdapter implements Adapter {
        private final StaticResourcesAdapter resourcesAdapter;
        private final ScreenAdapter screenAdapter;


        public RootAdapter(StaticResourcesAdapter resourcesAdapter,
        				ScreenAdapter screenAdapter) {
            this.screenAdapter = screenAdapter;
            this.resourcesAdapter = resourcesAdapter;
        }

        public void service(Request request, Response response) throws Exception {
            if(pathIsPresentIn(request)) {
                resourcesAdapter.service(request, response);
            } else {
                screenAdapter.service(response);
            }
        }
        ...
    }

Tests are still green.

Controlling the building

I’ve now the render of a building, but that render is static, I can’t really control it in any way.
Thus I’ll add a new test :


    @Test
    public void shouldRenderTheBuildingWithTheRightPositionAndDimensions() {
        User user = new User().lookAt(new HtmlScreen().addBuilding(50,30,40,80).render());
        assertThat(user.currentSight(), is("A Rectangle at [50,30], 40px high and 80px wide"));
    }

The test does not compile, I need the method “addBuilding”, easy added (empty, of course). Test is now failing, I always get the old rectangle in the old position. Fine.

This code makes all tests pass :


public class HtmlScreen implements Screen {
    private Building building = new Building(10, 10, 40, 50);

    public String render() {
        String start = "<html><head>" +
                "    <script type=\"text/javascript\" src=\"raphael-min.js\"></script>" +
                "    <script type=\"text/javascript\" charset=\"utf-8\">" +
                "        window.onload = function() {" +
                "            var map = new Raphael(0,0,600,400);";
        String end = "}</script></head><body></body></html>";
        return start + building.render() + end;
    }

    public Screen addBuilding(int x, int y, int height, int width) {
        building = new Building(x, y, height, width);
        return this;
    }
}

This code is ugly. The HtmlScreen is assembling the overall html, importing Raphael and composing the script. Building.render() is also strongly coupled with Raphael. It is also coupled with the fact that the Raphael canvas is named “map”, see for yourself :


    public String render() {
        return "map.rect(" + x + ","+ y + "," + width + "," + height + ");";
    }

This can’t do. I want everything related to Raphael to stay isolated and I want the HtmlScreen to focus on assembling the overall html, not the details of the script. I think I need a VectorGraphics object.


public class HtmlScreen {
    ...
    public String render() {
        return header() +
                vectorGraphics.include() +
                openScript() +
                openFunction() +
                vectorGraphics.init() +
                building.render(vectorGraphics) +
                closeFunction() +
                closeScript() +
                ending();
    }
    ...
}

public class VectorGraphics {

    public String include() {
        return "<script type=\"text/javascript\" src=\"raphael-min.js\"></script>";
    }
    
    public String init() {
        return "var map = new Raphael(0,0,600,400);";
    }

    public String rect(int x, int y, int width, int height) {
        return "map.rect(" + x + ","+ y + "," + width + "," + height + ");";
    }
}

public class Building {
    ...
    public String render(VectorGraphics vectorGraphics) {
        return vectorGraphics.rect(x, y, width, height);
    }
    ...
}

I don’t know if this idea of a vector graphics renderer, used by the building and by the HtmlScreen as well, represents a new and lower level of abstraction. In theory it is, as it manages every detail of the use of javascript for graphics, but strong abstractions aren’t always the most obvious ones, only tests will tell.

Advertisements

Web Apps in TDD, Part 2

Second step

The goal is still the same : showing a simple city map with the main character in the middle. I now have made sure I can answer http calls, thus I’ll pass to declare something about the contents of the answer itself. The simplest version of a city is a building (disclaimer : Christopher Alexander might not agree).

So, what’s a building? A rectangle, we said. But not just any rectangle, it should be shown on a browser, so it’s a rectangle within an html document.

A successful HttpAnswer must thus contain an html document.


@Test
public void shouldAnswerWithAnHtmlDocument() throws Exception {
    new Boss(PORT);
    assertThat(Http.callOn(PORT), is(HttpAnswer.with("<html><body></body></html>")));
}

When I run this test though, I get that PORT is already used. This can mean just one thing, my Boss server from the previous test is still running. I must stop it after the test.
Thus I change the previous test as well, to add a stop operation to Boss.


@Test
public void shouldAnswerHttpCall() throws Exception {
        Boss boss = new Boss(PORT);
        HttpAnswer answer = Http.callOn(PORT);
        boss.stop();
        assertThat(answer, is(HttpAnswer.ok()));
}

Then I implement it in Boss. This should do it :


public class Boss {
    private final SelectorThread selector;

    public Boss(int port) throws IOException, InstantiationException {
        selector = new SelectorThread();
        selector.setPort(port);
        selector.setAdapter(new AlwaysReturn(HttpAnswer.ok()));
        selector.listen();
    }

    public void stop() {
        selector.stopEndpoint();
    }
 }
 

Notice how the Grizzly selector now must be a field of Boss.
The test is still red, but now it’s not due to the need for the port, but because of this :


 Expected: is <org.boss.HttpAnswer@7f60c4b0[statusCode=200,payload=<html><body> </body></html>]>
     got: <org.boss.HttpAnswer@2a114025[statusCode=200,payload=<null>]>

Which is exactly what I need. I’ll make this pass then refactor some more.
To make this test pass the obvious thing to do is to let Boss add the html page to each answer.


public class Boss {
...
    public Boss(int port) throws IOException, InstantiationException {
        selector = new SelectorThread();
        selector.setPort(port);
        HttpAnswer answer = HttpAnswer.with("");
        selector.setAdapter(new AlwaysReturn(answer));
        selector.listen();
    }
...
}

I should not forget to let my little Http utility class parse the payload back (well, if I forgot my test would stay red, so I would know).


public class Http {
...
    public HttpAnswer call() throws IOException {
        Page page = client.getPage("http://localhost:" + port);
        int statusCode = page.getWebResponse().getStatusCode();
        String payload = page.getWebResponse().getContentAsString("UTF-8");
        return new HttpAnswer(statusCode, payload);
    }
...
}

The test is now green, I’m correctly sending back some basic html component.
Yet, there’s a surprise, the first test is not passing anymore. The previous test was expecting an empty http answer with just the success code 200.

Now, I might of course erase the old test, reasoning that it was just a stepping stone to the current test, which is, itself, just there to let me get closer to the goal of my first feature: showing the city map with the character in the middle.

Microdivergence

Yet I won’t. I’ll try to have both tests succeed.

If Boss is the game, then my html declaration is the screen on which the game will appear, and the first test is simply not expecting a screen.


public class BossBehavior {
    
    private static final int PORT = 11111;

    @Test
    public void shouldAnswerHttpCall() throws Exception {
        Boss boss = new Boss(PORT, new BlankScreen());
        HttpAnswer answer = Http.callOn(PORT);
        boss.stop();
        assertThat(answer, is(HttpAnswer.ok()));
    }

    @Test
    public void shouldAnswerWithAnHtmlDocument() throws Exception {
        Boss boss = new Boss(PORT, new HtmlScreen());
        HttpAnswer answer = Http.callOn(PORT);
        boss.stop();
        assertThat(answer, is(HttpAnswer.with("<html><body></body></html>")));
    }
}

Here it is, a new interface, representing the screen on which game objects will appear. The interface is still quite simple :


public interface Screen {
    String render();
}

And of course the HtmlScreen renders the html and body tags, while the BlankScreen renders nothing.

Now that all tests are green I’ll proceed to some more refactoring.

I don’t like the duplication of the boss.stop() operation I see in the test. I also don’t like my test to concern itself with two different different levels of abstraction : the overall behavior (it returns an html document) and its implementation (the html document is <html><body>…</html>)


public class BossBehavior {
    
    private static final int PORT = 11111;
    private Boss boss;

    @Test
    public void shouldAnswerHttpCall() throws Exception {
        boss = new Boss(PORT, new BlankScreen());
        assertThat(Http.callOn(PORT), is(HttpAnswer.ok()));
    }

    @Test
    public void shouldAnswerWithTheScreenContents() throws Exception {
        Screen screen = new HtmlScreen();
        boss = new Boss(PORT, screen);
        assertThat(Http.callOn(PORT), is(HttpAnswer.with(screen.render())));
    }

    @After
    public void stopBossServer() {
        boss.stop();
    }
}

Presently I added a new test which is one abstraction level lower than my first test, it’s not concerned about the whole system, just the game general presentation :


public class HtmlScreenBehavior {
    
    @Test
    public void shouldRenderAnHtmlDocument() {
        assertThat(new HtmlScreen().render(), is("<html><body></body></html>"));
    }
 
}

Notice how the concept of Screen was born to allow the two tests (“just return the 200 OK” and “return an html document”) to work at the same time.

The force of two similar-yet-diverging tests makes subsystems spring out. Waiting to have two divergent stories is often too late, while very small steps in a single story generate divergence at will.

The movement downwards

Finally, the third test and the Screen interface herald the birth of a gui layer. This is a movement which is very important.

Just as having a first test stating the basic broad facts of a system makes it flexible, using that same level of abstraction to declare all and everything in the system makes the tests rigid and instantly kills the design feedback from tdd.

When the next bit of the story can be declared by using a new, smaller part of the system, we need to focus on declaring it with just that part. If I manage to do it then it means that part has a reason to exist.

There’s something profoundly wrong in a system where the only useful object is the system itself. This is why acceptance tests have little value as a design tool.

There’s also something wrong in skipping the first tests of a new system just because that system happens to be a web application. It generates plenty of urban legends on how tdd works only for the business domain.

By the way, what’s this infamous business domain?

Anyway, let me move on with the next part : showing a building on my screen!

Reality check

My very first tests enforce lots of stuff, but I would really like to see how this system works for real. In case I forgot something.
The quickest way to do it is to make it run. I do this by this very complex method in the Boss class :


public class Boss() {
    public static void main(String... args) throws Exception {
        new Boss(11111, new HtmlScreen());
    }
    ...
}

Then I fire up my browser and type http://localhost:11111/
Surprise! the browser is not parsing the html!

In fact a browser will not parse the html unless the content is declared as being html.
Time to update my tests. I’ll just include the content type in my definition of correct HttpAnswer:


    public static HttpAnswer ok() {
        return new HttpAnswer(200,"","text/html");
    }

Now, when I perform an Http call I’ll also read the content type and use it to initialize the answer. Result, a red test, the very first one :


Expected: is ...HttpAnswer...contentType=text/html]
     got: ...HttpAnswer...contentType=text/plain]

Quick to fix, the HttpAnswer should set the contentType.


public class HttpAnswer{
...
    public void writeTo(Response response) throws IOException {
        response.setStatus(statusCode);
        response.setContentType(contentType);
        ByteChunk chunk = new ByteChunk(payload.length());
        chunk.setBytes(payload.getBytes("UTF-8"),0,payload.length());
        response.doWrite(chunk);
    }
...
}

Test green.
Just a little refactoring to clean this code a bit in order to maintain the same level of abstraction throughout the writeTo method :


    public void writeTo(Response response) throws IOException {
        response.setStatus(statusCode);
        response.setContentType(contentType);
        response.doWrite(payloadAsByteChunk());
    }

From Latex to Html

I always loved latex for generating documents. It’s such an elegant way for a developer to “develop” documents!

Then I wanted to produce posts from the latex source I had. This is text manipulation, so I picked ruby and started writing a parser. Then I stopped.

How many times did I write a parser? Probably half a dozen times, for different reasons, but nonetheless it always started with text and ended with nodes.

This time I looked around and found treetop, which lets you write grammars to parse languages into trees and then associate operations to nodes (like converting the node to html).

Of course I could have looked around for a latex-to-html converter or an existing treetop latex grammar, but I wouldn’t have learnt treetop itself.

I just committed the grammar, the ruby script that generates html from nodes and the ruby script that I used for developing it and that reads a .tex file and converts it to html.

git://github.com/inverno/Treetop-Latex-Grammar.git

The grammar is very limited, basically just what I need for my own paper, but, who knows, someone might enjoy playing with it.

Web Apps in TDD, Part 1

What’s this?

This is the beginning of the paper I was writing when discussing TDD with Matteo before he kindly invited me to the Italian Agile Day 2010.
After the talk, and in the days since, I was asked many times to provide more details and the source code.
The first request is certainly best served by publishing the aforementioned paper : it is not complete, so far it is 20 pages, which were enough for my talk, but I think it will take roughly twice that to describe TDD, the way I do it for web applications.
Nonetheless I’ll start posting the paper as it is right now, and more, as I continue the development and the paper itself.

I’ll abide to the second request once the full paper is complete by releasing the full sources along with the pdf version.

So, without further ado, here’s part one : page 1 to page 4.

The context

Here I mean to explain how I use test driven development to help me craft web applications. This is my way of doing it, as it stands now, having evolved during the years through the various systems I had the pleasure to create.

Since I’ve long wished to create a gta-like web game I’ll use it as an example for a new web application.
The game name is “Boss” and it should be played over a browser with a point-and-click interface.
When Boss is called by http it should offer a bird view of a set of city blocks, with the main character standing in the middle of the map. Each city block should be composed of multiple rectangles representing the various buildings.
The main character, a colored dot, should move in the direction clicked by the user’s mouse on the map.

An unusual first step

I’ll start with the first feature : when Boss is called by http it should offer a bird view of a set of city blocks, with the main character standing in the middle of the map.

Well, that’s certainly a lot of stuff to implement and I strongly doubt I’ll be able to implement it within a few minutes, so I’ll try to trim down the problem to be able to write the first test and its solution quickly.

With my first test I’ll just make sure that Boss answers to an http call succesfully. For the sake of brevity I’ll skip a couple loops and presume that a class “Boss” should exist, instead of refactoring it out of the test itself. So, my first test looks like this :


public class BossBehavior {

    @Test
    public void shouldAnswerHttpCall() throws IOException {
        new Boss(8080);
        WebClient client = new WebClient();
        Page page = client.getPage("http://localhost:8080");
        assertThat(page.getWebResponse().getStatusCode(), is(200));
    }

}

WebClient comes with the htmlunit framework, which turns out to be a quick way to invoke an http endpoint.

Of course this fails, as expected.

So I’ll try to make it pass. I don’t plan to re-implement the http protocol, so I’ll go shopping for a nice http server. In the past I used Jetty, but this time I’ll try Grizzly.

After a brief tour on the web I try this :


public class Boss {
    
    public Boss(int port) throws IOException, InstantiationException {
        SelectorThread selector = new SelectorThread();
        selector.setPort(port);
        selector.listen();
    }

}

This returns a nice null pointer exception. To be specific I see this line :


java.lang.NullPointerException
	at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:824)

Hm, well, I didn’t pass an Adapter to the SelectorThread. Some more reading and I get this :


public class Boss {
    
    public Boss(int port) throws IOException, InstantiationException {
        SelectorThread selector = new SelectorThread();
        selector.setPort(port);
        selector.setAdapter(new AlwaysReturn200Ok());
        selector.listen();
    }

    private static class AlwaysReturn200Ok implements Adapter {
        public void service(Request request, Response response) throws Exception {
            response.setStatus(200);
        }

        public void afterService(Request request, Response response) throws Exception {}
    }
}

It works fine, the test is green.
Now I’ll proceed to some refactoring, but first, a brief note : is this a unit test?

Actually, I don’t care. The only thing which I care about is that this test is quick, repeatable, short, simple and it will work everywhere I have port 8080 available.

In fact, port 8080 is quite used nowadays (default tomcat servers for development purposes and so on…), let’s change that to 11111 from now on. Just to stay safe.

And now some refactoring

First the test, when I switched to port 11111 I forgot to update the url on which WebClient was performing the call, a nice reminder of that clumsy duplication I introduced.
Also, the test is a bit too involved in the details of WebClient, let me fix this before moving to refactoring Boss itself.

I stop when I get to this :


public class BossBehavior {
    private static final int OK = 200;
    private static final int PORT = 11111;

    @Test
    public void shouldAnswerHttpCall() throws Exception {
        new Boss(PORT);
        assertThat(Http.callOn(PORT), is(OK));
    }
}

Http contains little special, just the call to WebClient and the extraction of the status code.

Now I’ll move to Boss. Currently Boss is just a tiny http server which always answers 200 OK. From a responsibility point of view there’s little to do, but I definitely don’t like that “200” which appears both in the test and the solution.

In the context of my application the code 200 is just a way to say the answer is positive. I don’t like using primitives to represent high-level concepts, such as “positive answer” and I certainly don’t like duplicated primitive values.


public class HttpAnswer {

    private final int statusCode;
       
    public static HttpAnswer ok() {
        return new HttpAnswer(200);
    }

    public HttpAnswer(int statusCode) {
        this.statusCode = statusCode;
    }

    public void writeTo(Response response) {
        response.setStatus(statusCode);
    }
...
}

While a bit verbose, this class removes the status 200 duplication in test and solution code and it slims down both, while letting me express the intent more clearly. Here’s the current situation for both test and solution :


public class BossBehavior {
    
    private static final int PORT = 11111;

    @Test
    public void shouldAnswerHttpCall() throws Exception {
        new Boss(PORT);
        assertThat(Http.callOn(PORT), is(HttpAnswer.ok()));
    }
}

public class Boss {
    
    public Boss(int port) throws IOException, InstantiationException {
        SelectorThread selector = new SelectorThread();
        selector.setPort(port);
        selector.setAdapter(new AlwaysReturn(HttpAnswer.ok()));
        selector.listen();
    }

}

To make the tests assertions work and to get nice messages in the future I’ll implement equals, hashcode and toString for HttpAnswer. I use the excellent EqualsBuilder, HashcodeBuilder and ToStringBuilder classes from apache.


public class HttpAnswer {
...
    @Override
    public boolean equals(Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}

The Software Craftsman’s Guide to the World

A few weeks ago I started this map after a discussion on the Software Craftsmanship list.

The idea is simple : there are developers looking forward to meet others for a discussion or a bit of pairing, there are companies looking forward to welcome people to work with them for a while and share ideas, there are houses which may offer hospitality to fellow developers, so why not putting them all on a map with contact information?

I mentioned this idea at the Italian Agile Day 2010 and a few people have been asking me for more information, so here it is :

The Software Craftsman’s Guide to the World

On prefixes and suffixes

Lately I’m doing a bit of C# programming, as I’m having fun with the Unity game engine and suite (and boy, it is cool!). Unity allows you to write game logic in C#, JavaScript and Boo.
I started with JavaScript, but then I switched to C#, just for the sake of it.

There I had quite a surprise. C# base libraries (and thus, I would expect, most of C# code out there) prefix interfaces with “I”!!


IList, IDictionary, IWhatever.

When C# first came out and later on as new versions appeared I glanced at the language features and I liked what I saw, especially since C# seemed far bolder than Java in updating its syntax to new features, and doing it well (my feelings where kind of confirmed when Neal Gafter moved over to Microsoft to work on .NET).

That said, finding this naming convention so deeply rooted in C# culture pains me to no end.

I’ve had a look around and I saw quite a few blogs criticizing it, yet the real point about why the “I” for Interface is not a good idea didn’t appear very often, and when it did, it seemed like an afterthought.

I will express this point with a question : “Why would a client ever need to know that some type it is using is an interface?”.

“Client” here means any bit of code using some other bit of code :


oneMethod() {
IList list = new ArrayList();

In this exemple “oneMethod” is the client of the list.


anotherMethod(IList list) {
list.doSomething();
}

Here again, another method is a client of the list.

For the purpose of expressing a problem’s domain and the logic for solving it, advertising the fact that IList is an interface is uninteresting.
The client code using an interface has no need to know about it, nor the developer reading that code!

What is even more important is that prefixing the interface shows that the interface is considered just a technical “trick”, a convenient, but meaningless literal which happens to be part of the language.

Interfaces must always represent the core roles of a system, the main actors on stage. They must do so crisply and unambiguously, as those are the actors we will spend most of our time looking at.

If my system sends payments over the network I do expect that the main roles get first-class names : Payment, Connection, Customer.
If some of these happen to be interfaces I do expect their implementations to get second-class, specific names, since I won’t look at them often, unless I need to delve one step lower in the details : DirectPayment, DelayedPayment, TCPConnection, BankCustomer, InsuranceCustomer…

When observing “I” infested code I notice that the first-class name (Customer, Connection..) is given to the main implementation of the interface, or, worse, the sole implementation of the interface. In this case the interface is perceived as boilerplate (and it is likely so) : I need to have an interface, so let’s extract it and put a convenient prefix before it.

Other times the use of prefixes seems to arise from having apparently expended all “good” names. I stress the “apparently” : I’ve yet to find a case where it is impossible to give both a meaningful name to the interface, representing the overall concept for the system, and to the implementations, representing the details.

Provided that one stops to think long enough.

Finding good names needs time. A serious naming effort is often the beginning of a new understanding; usually that’s the understanding that our roles are wrong and we should look for better ones, which leads to further costs.

By using plenty of prefixes and suffixes instead (I, A, Manager, Processor, Decorator, Impl, Service, Factory, Bean…), we can write code much faster, it spares us much of the thinking, in fact, most of the time we can just stop thinking about names, almost anything can be forced to fall within the range of a random combination of prefixes and suffixes :


ITransferManager, ProcessorService, ServiceFactory, ProcessorDecoratorImpl

and, of course, DecoratorProcessorImpl !

While here is a sample of what we might be missing (traslating 1 on 1 to meaningful names) :


PostOffice, MailBox, MailAccount, RemoteMailBox, UnsortedMail

By using prefixes and suffixes we are truly wasting the semantic potential of our code.

It’s the same kind of waste that we could obtain by naming functions after the number of their parameters : setString1(“”), setString2(8,””).

We wouldn’t dream of not naming the second setString as what it actually is : setSubstring.
Yet we do so all the time with classes.

Often we do this for the sake of “standardization”. This a classic of groups where a chief developer puts down the architecture and then enforces a set of rules for class names : “And thou shall call ye spring initialised objects “Beans”, and those which are not shall be “Factories”…”.

Standardization is nice, and it is perhaps the only positive point I see in pattern-based prefixes and suffixes, but the standardization effort happens long before the real domain of the system is clear and has slowed down evolving; this leaves the standardization authority with pretty few clues on proper names and so it falls back to enforcing technical roles. The developers behind the lead will have one less reason to look for good names : they are not expected to do so.

So, to sum it all up, when prefixes and suffixes see large use, the favoured programming habit is often “write fast, read slow”. This is the recipe for huge, bloated code, where technical details get advertised everywhere and arise to prominence in spite of the problem domain. And I don’t like it.

I’m looking at you, Controller.