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

Sample for lift-ng: Micro-burn 1.0.0 released

During a last few evenings in my free time I've worked on mini-application called micro-burn. The idea of it appear from work with Agile Jira in our commercial project. This is a great tool for agile projects management. It has inline tasks edition, drag & drop board, reports and many more, but it also have a few drawbacks that turn down our team motivation.

Motivation

From time to time our sprints scope is changing. It is not a big deal because we are trying to be agile :-) but Jira's burndowchart in this situation draw a peek. Because in fact that chart shows scope changes not a real burndown. It means, that chart cannot break down an x-axis if we really do more than we were planned – it always stop on at most zero.

Also for better progress monitoring we've started to split our user stories to technical tasks and estimating them. Original burndowchart doesn't show points from technical tasks. I can find motivation of this – user story almost finished isn't finished at all until user can use it. But in the other hand, if we know which tasks is problematic we can do some teamwork to move it on.

So I realize that it is a good opportunity to try some new approaches and tools.

Tools

I've started with lift framework. In the World of Single Page Applications, this framework has more than simple interface for serving REST services. It comes with awesome Comet support. Comet is a replacement for WebSockets that run on all browsers. It supports long polling and transparent fallback to short polling if limit of client connections exceed. In backend you can handle pushes in CometActor. For further reading take a look at Roundtrip promises

But lift framework is also a kind of framework of frameworks. You can handle own abstraction of CometActors and push to client javascript that shorten up your way from server to client. So it was the trigger for author of lift-ng to make a lift with Angular integration that is build on top of lift. It provides AngularActors from which you can emit/broadcast events to scope of controller. NgModelBinders that synchronize your backend model with client scope in a few lines! I've used them to send project state (all sprints and thier details) to client and notify him about scrum board changes. My actor doing all of this hard work looks pretty small:

Lift-ng also provides factories for creating of Angular services. Services could respond with futures that are transformed to Angular promises in-fly. This is all what was need to serve sprint history:

And on the client side - use of service:


In my opinion this two frameworks gives a huge boost in developing of web applications. You have the power of strongly typing with Scala, you can design your domain on Actors and all of this with simplicity of node.js – lack of json trasforming boilerplate and dynamic application reload.

DDD + Event Sourcing

I've also tried a few fresh approaches to DDD. I've organize domain objects in actors. There are SprintActors with encapsulate sprint aggregate root. Task changes are stored as events which are computed as a difference between two boards states. When it should be provided a history of sprint, next board states are computed from initial state and sequence of events. So I realize that the best way to keep this kind of event sourcing approach tested is to make random tests. This is a test doing random changes at board, calculating events and checking if initial state + events is equals to previously created state:



First look

Screenshot of first version:


If you want to look at this closer, check the source code or download ready to run fatjar on github.During a last few evenings in my free time I've worked on mini-application called micro-burn. The idea of it appear from work with Agile Jira in our commercial project. This is a great tool for agile projects management. It has inline tasks edition, drag & drop board, reports and many more, but it also have a few drawbacks that turn down our team motivation.

Grails session timeout without XML

This article shows clean, non hacky way of configuring featureful event listeners for Grails application servlet context. Feat. HttpSessionListener as a Spring bean example with session timeout depending on whether user account is premium or not.

Common approaches

Speaking of session timeout config in Grails, a default approach is to install templates with a command. This way we got direct access to web.xml file. Also more unnecessary files are created. Despite that unnecessary files are unnecessary, we should also remember some other common knowledge: XML is not for humans.

Another, a bit more hacky, way is to create mysterious scripts/_Events.groovy file. Inside of which, by using not less enigmatic closure: eventWebXmlEnd = { filename -> ... }we can parse and hack into web.xml with a help of XmlSlurper.
Even though lot of Grails plugins do it similar way, still it’s not really straightforward, is it? Besides, where’s the IDE support? Hello!?

Examples of both above ways can be seen on StackOverflow.

Simpler and cleaner way

By adding just a single line to the already generated init closure we have it done:
class BootStrap {

def init = { servletContext ->
servletContext.addListener(OurListenerClass)
}
}

Allrighty, this is enough to avoid XML. Sweets are served after the main course though :)

Listener as a Spring bean

Let us assume we have a requirement. Set a longer session timeout for premium user account.
Users are authenticated upon session creation through SSO.

To easy meet the requirements just instantiate the CustomTimeoutSessionListener as Spring bean at resources.groovy. We also going to need some source of the user custom session timeout. Let say a ConfigService.
beans = {    
customTimeoutSessionListener(CustomTimeoutSessionListener) {
configService = ref('configService')
}
}

With such approach BootStrap.groovy has to by slightly modified. To keep control on listener instantation, instead of passing listener class type, Spring bean is injected by Grails and the instance passed:
class BootStrap {

def customTimeoutSessionListener

def init = { servletContext ->
servletContext.addListener(customTimeoutSessionListener)
}
}

An example CustomTimeoutSessionListener implementation can look like:
import javax.servlet.http.HttpSessionEvent    
import javax.servlet.http.HttpSessionListener
import your.app.ConfigService

class CustomTimeoutSessionListener implements HttpSessionListener {

ConfigService configService

@Override
void sessionCreated(HttpSessionEvent httpSessionEvent) {
httpSessionEvent.session.maxInactiveInterval = configService.sessionTimeoutSeconds
}

@Override
void sessionDestroyed(HttpSessionEvent httpSessionEvent) { /* nothing to implement */ }
}
Having at hand all power of the Spring IoC this is surely a good place to load some persisted user’s account stuff into the session or to notify any other adequate bean about user presence.

Wait, what about the user context?

Honest answer is: that depends on your case. Yet here’s an example of getSessionTimeoutMinutes() implementation using Spring Security:
import org.springframework.security.core.context.SecurityContextHolder    

class ConfigService {

static final int 3H = 3 * 60 * 60
static final int QUARTER = 15 * 60

int getSessionTimeoutSeconds() {

String username = SecurityContextHolder.context?.authentication?.principal
def account = Account.findByUsername(username)

return account?.premium ? 3H : QUARTER
}
}
This example is simplified. Does not contain much of defensive programming. Just an assumption that principal is already set and is a String - unique username. Thanks to Grails convention our ConfigService is transactional so the Account domain class can use GORM dynamic finder.
OK, config fetching implementation details are out of scope here anyway. You can get, load, fetch, obtain from wherever you like to. Domain persistence, principal object, role config, external file and so on...

Any gotchas?

There is one. When running grails test command, servletContext comes as some mocked class instance without addListener method. Thus we going to have a MissingMethodException when running tests :(

Solution is typical:
def init = { servletContext ->
if (Environment.current != Environment.TEST) {
servletContext.addListener(customTimeoutSessionListener)
}
}
An unnecessary obstacle if you ask me. Should I submit a Jira issue about that?

TL;DR

Just implement a HttpSessionListener. Create a Spring bean of the listener. Inject it into BootStrap.groovy and call servletContext.addListener(injectedListener).