Writer versus Constructor

What’s the favorite toy from your childhood? For me, both my sisters and pretty much everyone I know that would be Lego. If you could only afford it (and in the times when I was a kid, that wasn’t so easy in the post-soviet Poland), there was no greater fun, than the joy of unlimited freedom to create whatever you can only imagine. And the fact, that you had limited resources wasn’t a real obstacle. It was a challenge.

Nearly all the programmers I know, fell in love with programming because of the same reason. To be able to put pure ideas to life, to create something meaningful out of nothing. Truth is, no other matter is so flexible, as the stuff we work with.

We are developers because we love to construct things that work. To give soul to the machine. To make it act on our behalf. It’s like magic.

That’s why it is so difficult for us to understand, that a real software craftsman is a writer, not a constructor.

Uncle Bob is talking about it at the beginning of “Clean Code”. When you are writing code, you are actually reading a lot more. How is that possible? Let’s have a look at an example: you have a project going, and you take a new feature from the Scrum/Kanban wall of features. And you:

  1. read the code to find a place where putting some more code will give you the result you seek
  2. read the code to better understand the surroundings, to eliminate potential side effects of your changes
  3. write the test and the code that does what the feature is expected to do

You can start with an acceptance test first, but that only changes the order, not the fact, that the proportions of reading to writing, are always in favor of reading. Big time.

So, if reading takes so much time, how important is to make things readable?

People are working hard to learn how to write faster, how not to use mouse in their IDE, they memorize all the keyboard shortcuts, use templates and so on, but the speed up is not significant in real work. Why? Because we are only writing code 1/10 of our time. The rest is spent on reading and thinking.

A good craftsman is a good writer, because he makes the code readable, easy to grasp, easy to understand. There is a huge shift in mentality, between a constructor and a writer. Above all, the constructor’s goal is to make things work. The writer’s goal, on the other hand, is to make things easy to understand.

The question is, who are we writing code for? The computer? Hell no. If that was true, we would be still writing in an assembly language (or maybe even in a machine code). The whole point of procedural, functional, object oriented languages was to make it easier for us to understand the code. And that’s because we don’t write the code for the computer.

We write it for other programmers.

To make the shift in mentality easier, let mi show you the differences in mindsets, between the constructor and the writer.


The Constructor

The constructor is in love with technology for the sake of technology. He likes to “technologically masturbate” himself with new toys. He thinks that simplicity is for pussies, the real thing is always complex. He never removes anything, always adds more. He doesn’t care that he cannot understand how his earlier solutions work, if they work why would he want to change them? He creates monsters like EJB1/2, that can do pretty much everything, but nobody is able to handle them. The he writes software to be able to use/confgure the software he has written before, because it’s already too complex for anybody (maybe except for him) to understand how to use it directly.

A bigger framework is a solution to his every problem. And even if it’s a new problem, he tries to modify his beloved one-to-rule-them-all tool, to be able to solve it. He is dreaming about the day, that he will have a single, big, multipurpose, futuristic wrench that works as if by magic, and does everything, from printing log files to saving the planet.

The constructor works best alone. He gets angry at people that cannot understand his programs in a second. When he works with other programmers, he is always afraid, he doesn’t like others to play with his tools. When they try to do pretty much anything, they always blow something else up. Because of unforeseen side effects, a small change can devastate days of work. And it happens a lot. It gets messy, so he hates to work with others.

The Writer

The writer reads a lot, so he wants to make his code as readable, as simple as possible. He learns stuff like DSLs, patterns, eXtreme Programming, to make things easy. Easy is his keyword. He cares less about frameworks. He usually knows a few languages from different worlds, because he believes there is no single silver bullet, and different solutions are better for different problems. His code has few comments, because it doesn’t need them. His code is self-documenting. His code is expressive. His code is simple, simplicity is his main value. Brilliant things are simple.

The writer always thinks about his reader. He walks hand to hand with his readers. He guides them, he cares for them. He never leaves them in the dark. His skills are in communication: he wants his intentions to be understood.

The writer works like a sniper. His changes (whether bug fixes or new features) are minimal, but the effects are exactly as expected. He never does Shotgun Surgery. He doesn’t violate DRY. He is a precise man and he works with a scalpel. His code is side-effect free, simple and readable, so he knows where and how to hit. He knows what the effects will be. He keeps accidental complexity low.

The writer is agile. He doesn’t set up traps, and he doesn’t fall into traps. He works hard to master basic skills. He believes that without those basic skills, no framework can save him anyway.

The writer likes to work with other programmers. He is using pair programming and code reviews to make sure that his code is easy to understand by others. He wants to have another mind watching his back, and catching him when he falls. He is supportive, he is friendly. He understands that no man is an island, and that the quality of his work will be measured by the number of WTFs shouted by other developers.

A good craftsman is a good writer.

And you know what one of the most successful writers of recent times, Stephen King, says?

That he’s only a craftsman.

PS: all the pictures are from Fallout games.

PS2: I’ve failed at giving appropriate credits to the author of the concept of programmer as a constructor. Let me fix that right away: the source of the idea that a programmer as a writer has opposition in programmer-constructor comes from a post by Andrzej Szczodrak that you can find in here

You May Also Like

Spring Security by example: securing methods

This is a part of a simple Spring Security tutorial:

1. Set up and form authentication
2. User in the backend (getting logged user, authentication, testing)
3. Securing web resources
4. Securing methods
5. OpenID (login via gmail)
6. OAuth2 (login via Facebook)
7. Writing on Facebook wall with Spring Social

Securing web resources is all nice and cool, but in a well designed application it's more natural to secure methods (for example on backend facade or even domain objects). While we may get away with role-based authorization in many intranet business applications, nobody will ever handle assigning roles to users in a public, free to use Internet service. We need authorization based on rules described in our domain.

For example: there is a service AlterStory, that allows cooperative writing of stories, where one user is a director (like a movie director), deciding which chapter proposed by other authors should make it to the final story.

The method for accepting chapters, looks like this:

Read more »

CasperJS for Java developers

Why CasperJS

Being a Java developer is kinda hard these days. Java may not be dead yet, but when keeping in sync with all the hipster JavaScript frameworks could make us feel a bit outside the playground. It’s even hard to list JavaScript frameworks with latest releases on one website.

In my current project, we are using AngularJS. It’a a nice abstraction of MV* pattern in frontend layer of any web application (we use Grails underneath). Here is a nice article with an 8-point Win List of Angular way of handling AJAX calls and updating the view. So it’s not only a funny new framework but a truly helper of keeping your code clean and neat.

But there is also another area when you can put helpful JS framework in place of plan-old-java one - functional tests. Especially when you are dealing with one page app with lots of asynchronous REST/JSON communication.

Selenium and Geb

In Java/JVM project the typical is to use Selenium with some wrapper like Geb. So you start your project, setup your CI-functional testing pipeline and… after 1 month of coding your tests stop working and being maintainable. The frameworks itselves are not bad, but the typical setup is so heavy and has so many points of failure that keeping it working in a real life project is really hard.

Here is my list of common myths about Selenium: * It allows you to record test scripts via handy GUI - maybe some static request/response sites. In modern web applications with asynchronous REST/JSON communication your tests must contain a lot of “waitFor” statements and you cannot automate where these should be included. * It allows you to test your web app against many browsers - don’t try to automate IE tests! You have to manually open your app in IE to see how it actually bahaves! * It integrates well with continuous integration servers like Jenkins - you have to setup Selenium Grid on server with X installed to run tests on Chrome or Firefox and a Windows server for IE. And the headless HtmlUnit driver lacks a lot of JS support.

So I decided to try something different and introduce a bit of JavaScript tooling in our project by using CasperJS.

Introduction

CasperJS is simple but powerful navigation scripting & testing utility for PhantomJS - scritable headless WebKit (which is an rendering engine used by Safari and Chrome). In short - CasperJS allows you to navigate and make assertions about web pages as they’d been rendered in Google Chrome. It is enough for me to automate the functional tests of my application.

If you want a gentle introduction to the world of CasperJS I suggest you to read: * Official website, especially installation guide and API * Introductionary article from CasperJS creator Nicolas Perriault * Highlevel testing with CasperJS by Kevin van Zonneveld * grails-angular-scaffolding plugin by Rob Fletcher with some working CasperJS tests

Full example

I run my test suite via following script:

casperjs test --direct --log-level=debug --testhost=localhost:8080 --includes=test/casper/includes/casper-angular.coffee,test/casper/includes/pages.coffee test/casper/specs/

casper-angular.coffe

casper.test.on "fail", (failure) ->
    casper.capture(screenshot)

testhost   = casper.cli.get "testhost"
screenshot = 'test-fail.png'

casper
    .log("Using testhost: #{testhost}", "info")
    .log("Using screenshot: #{screenshot}", "info")

casper.waitUntilVisible = (selector, message, callback) ->
    @waitFor ->
        @visible selector
    , callback, (timeout) ->
        @log("Selector [#{selector}] not visible, failing")
        withParentSelector selector, (parent) ->
            casper.log("Output of parent selector [#{parent}]")
            casper.debugHTML(parent)
        @echo message, "RED_BAR"
        @capture(screenshot)
        @test.fail(f("Wait timeout occured (%dms)", timeout))

withParentSelector = (selector, callback) ->
    if selector.lastIndexOf(" ") > 0
       parent = selector[0..selector.lastIndexOf(" ")-1]
       callback(parent)

Sample pages.coffee:

x = require('casper').selectXPath

class EditDocumentPage

    assertAt: ->
        casper.test.assertSelectorExists("div.customerAccountInfo", 'at EditDocumentPage')

    templatesTreeFirstCategory: 'ul.tree li label'
    templatesTreeFirstTemplate: 'ul.tree li a'
    closePreview: '.closePreview a'
    smallPreview: '.smallPreviewContent img'
    bigPreview: 'img.previewImage'
    confirmDelete: x("//div[@class='modal-footer']/a[1]")

casper.editDocument = new EditDocumentPage()

End a test script:

testhost = casper.cli.get "testhost" or 'localhost:8080'

casper.start "http://#{testhost}/app", ->
    @test.assertHttpStatus 302
    @test.assertUrlMatch /\/fakeLogin/, 'auto login'
    @test.assert @visible('input#Create'), 'mock login button'
    @click 'input#Create'

casper.then ->
    @test.assertUrlMatch /document#\/edit/, 'new document'
    @editDocument.assertAt()
    @waitUntilVisible @editDocument.templatesTreeFirstCategory, 'template categories not visible', ->
        @click @editDocument.templatesTreeFirstCategory
        @waitUntilVisible @editDocument.templatesTreeFirstTemplate, 'template not visible', ->
            @click @editDocument.templatesTreeFirstTemplate

casper.then ->
    @waitUntilVisible @editDocument.smallPreview, 'small preview not visible', ->
        # could be dblclick / whatever
        @mouseEvent('click', @editDocument.smallPreview)

casper.then ->
    @waitUntilVisible @editDocument.bigPreview, 'big preview should be visible', ->
        @test.assertEvalEquals ->
            $('.pageCounter').text()
        , '1/1', 'page counter should be visible'
        @click @editDocument.closePreview

casper.then ->
    @click 'button.cancel'
    @waitUntilVisible '.modal-footer', 'delete confirmation not visible', ->
        @click @editDocument.confirmDelete

casper.run ->
    @test.done()

Here is a list of CasperJS features/caveats used here:

  • Using CoffeeScript is a huge win for your test code to look neat
  • When using casper test command, beware of different (than above articles) logging setup. You can pass --direct --log-level=debug from commandline for best results. Logging is essential here since Phantom often exists without any error and you do want to know what just happened.
  • Extract your helper code into separate files and include them by using --includes switch.
  • When passing server URL as a commandline switch remember that in CoffeeScript variables are not visible between multiple source files (unless getting them via window object)
  • It’s good to override standard waitUntilVisible with capting a screenshot and making a proper log statement. In my version I also look for a parent selector and debugHTML the content of it - great for debugging what is actually rendered by the browser.
  • Selenium and Geb have a nice concept of Page Objects - an abstract models of pages rendered by your application. Using CoffeeScript you can write your own classes, bind selectors to properties and use then in your code script. Assigning the objects to casper instance will end up with quite nice syntax like @editDocument.assertAt().
  • There is some issue with CSS :first and :last selectors. I cannot get them working (but maybe I’m doing something wrong?). But in CasperJS you can also use XPath selectors which are fine for matching n-th child of some element (x("//div[@class='modal-footer']/a[1]")).
    Update: :first and :last are not CSS3 selectors, but JQuery ones. Here is a list of CSS3 selectors, all of these are supported by CasperJS. So you can use nth-child(1) is this case. Thanks Andy and Nicolas for the comments!

Working with CasperJS can lead you to a few hour stall, but after getting things working you have a new, cool tool in your box!