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

Multi module Gradle project with IDE support

This article is a short how-to about multi-module project setup with usage of the Gradle automation build tool.

Here's how Rich Seller, a StackOverflow user, describes Gradle:
Gradle promises to hit the sweet spot between Ant and Maven. It uses Ivy's approach for dependency resolution. It allows for convention over configuration but also includes Ant tasks as first class citizens. It also wisely allows you to use existing Maven/Ivy repositories.
So why would one use yet another JVM build tool such as Gradle? The answer is simple: to avoid frustration involved by Ant or Maven.

Short story

I was fooling around with some fresh proof of concept and needed a build tool. I'm pretty familiar with Maven so created project from an artifact, and opened the build file, pom.xml for further tuning.
I had been using Grails with its own build system (similar to Gradle, btw) already for some time up then, so after quite a time without Maven, I looked on the pom.xml and found it to be really repulsive.

Once again I felt clearly: XML is not for humans.

After quick googling I found Gradle. It was still in beta (0.8 version) back then, but it's configured with Groovy DSL and that's what a human likes :)

Where are we

In the time Ant can be met but among IT guerrillas, Maven is still on top and couple of others like for example Ivy conquer for the best position, Gradle smoothly went into its mature age. It's now available in 1.3 version, released at 20th of November 2012. I'm glad to recommend it to anyone looking for relief from XML configured tools, or for anyone just looking for simple, elastic and powerful build tool.

Lets build

I have already written about basic project structure so I skip this one, reminding only the basic project structure:
<project root>

├── build.gradle
└── src
├── main
│ ├── java
│ └── groovy

└── test
├── java
└── groovy
Have I just referred myself for the 1st time? Achievement unlocked! ;)

Gradle as most build tools is run from a command line with parameters. The main parameter for Gradle is a 'task name', for example we can run a command: gradle build.
There is no 'create project' task, so the directory structure has to be created by hand. This isn't a hassle though.
Java and groovy sub-folders aren't always mandatory. They depend on what compile plugin is used.

Parent project

Consider an example project 'the-app' of three modules, let say:
  1. database communication layer
  2. domain model and services layer
  3. web presentation layer
Our project directory tree will look like:
the-app

├── dao-layer
│ └── src

├── domain-model
│ └── src

├── web-frontend
│ └── src

├── build.gradle
└── settings.gradle
the-app itself has no src sub-folder as its purpose is only to contain sub-projects and build configuration. If needed it could've been provided with own src though.

To glue modules we need to fill settings.gradle file under the-app directory with a single line of content specifying module names:
include 'dao-layer', 'domain-model', 'web-frontend'
Now the gradle projects command can be executed to obtain such a result:
:projects

------------------------------------------------------------
Root project
------------------------------------------------------------

Root project 'the-app'
+--- Project ':dao-layer'
+--- Project ':domain-model'
\--- Project ':web-frontend'
...so we know that Gradle noticed the modules. However gradle build command won't run successful yet because build.gradle file is still empty.

Sub project

As in Maven we can create separate build config file per each module. Let say we starting from DAO layer.
Thus we create a new file the-app/dao-layer/build.gradle with a line of basic build info (notice the new build.gradle was created under sub-project directory):
apply plugin: 'java'
This single line of config for any of modules is enough to execute gradle build command under the-app directory with following result:
:dao-layer:compileJava
:dao-layer:processResources UP-TO-DATE
:dao-layer:classes
:dao-layer:jar
:dao-layer:assemble
:dao-layer:compileTestJava UP-TO-DATE
:dao-layer:processTestResources UP-TO-DATE
:dao-layer:testClasses UP-TO-DATE
:dao-layer:test
:dao-layer:check
:dao-layer:build

BUILD SUCCESSFUL

Total time: 3.256 secs
To use Groovy plugin slightly more configuration is needed:
apply plugin: 'groovy'

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
groovy 'org.codehaus.groovy:groovy-all:2.0.5'
}
At lines 3 to 6 Maven repositories are set. At line 9 dependency with groovy library version is specified. Of course plugin as 'java', 'groovy' and many more can be mixed each other.

If we have settings.gradle file and a build.gradle file for each module, there is no need for parent the-app/build.gradle file at all. Sure that's true but we can go another, better way.

One file to rule them all

Instead of creating many build.gradle config files, one per each module, we can use only the parent's one and make it a bit more juicy. So let us move the the-app/dao-layer/build.gradle a level up to the-app/build-gradle and fill it with new statements to achieve full project configuration:
def langLevel = 1.7

allprojects {

apply plugin: 'idea'

group = 'com.tamashumi'
version = '0.1'
}

subprojects {

apply plugin: 'groovy'

sourceCompatibility = langLevel
targetCompatibility = langLevel

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
groovy 'org.codehaus.groovy:groovy-all:2.0.5'
testCompile 'org.spockframework:spock-core:0.7-groovy-2.0'
}
}

project(':dao-layer') {

dependencies {
compile 'org.hibernate:hibernate-core:4.1.7.Final'
}
}

project(':domain-model') {

dependencies {
compile project(':dao-layer')
}
}

project(':web-frontend') {

apply plugin: 'war'

dependencies {
compile project(':domain-model')
compile 'org.springframework:spring-webmvc:3.1.2.RELEASE'
}
}

idea {
project {
jdkName = langLevel
languageLevel = langLevel
}
}
At the beginning simple variable langLevel is declared. It's worth knowing that we can use almost any Groovy code inside build.gradle file, statements like for example if conditions, for/while loops, closures, switch-case, etc... Quite an advantage over inflexible XML, isn't it?

Next the allProjects block. Any configuration placed in it will influence - what a surprise - all projects, so the parent itself and sub-projects (modules). Inside of the block we have the IDE (Intellij Idea) plugin applied which I wrote more about in previous article (look under "IDE Integration" heading). Enough to say that with this plugin applied here, command gradle idea will generate Idea's project files with modules structure and dependencies. This works really well and plugins for other IDEs are available too.
Remaining two lines at this block define group and version for the project, similar as this is done by Maven.

After that subProjects block appears. It's related to all modules but not the parent project. So here the Groovy language plugin is applied, as all modules are assumed to be written in Groovy.
Below source and target language level are set.
After that come references to standard Maven repositories.
At the end of the block dependencies to groovy version and test library - Spock framework.

Following blocks, project(':module-name'), are responsible for each module configuration. They may be omitted unless allProjects or subProjects configure what's necessary for a specific module. In the example per module configuration goes as follow:
  • Dao-layer module has dependency to an ORM library - Hibernate
  • Domain-model module relies on dao-layer as a dependency. Keyword project is used here again for a reference to other module.
  • Web-frontend applies 'war' plugin which build this module into java web archive. Besides it referes to domain-model module and also use Spring MVC framework dependency.

At the end in idea block is basic info for IDE plugin. Those are parameters corresponding to the Idea's project general settings visible on the following screen shot.


jdkName should match the IDE's SDK name otherwise it has to be set manually under IDE on each Idea's project files (re)generation with gradle idea command.

Is that it?

In the matter of simplicity - yes. That's enough to automate modular application build with custom configuration per module. Not a rocket science, huh? Think about Maven's XML. It would take more effort to setup the same and still achieve less expressible configuration quite far from user-friendly.

Check the online user guide for a lot of configuration possibilities or better download Gradle and see the sample projects.
As a tasty bait take a look for this short choice of available plugins:
  • java
  • groovy
  • scala
  • cpp
  • eclipse
  • netbeans
  • ida
  • maven
  • osgi
  • war
  • ear
  • sonar
  • project-report
  • signing
and more, 3rd party plugins...

Multi phased processing in scala

Last time in our project we had to add progress bar for visualization of long time running process. Process was made of a few phases and we had to print in which phase we currently are. In first step we conclude that we need to create a class of Progre...