The Devil’s in the Details [of Software Development]

It’s always a bit upsetting when I experience that people don’t know concepts related to software development that I think are very common, because lacking knowledge about these “details” can lead to big misunderstandings.

Software Development Cat

I prefer to think that it’s my fault, our fault as an industry, not theirs fault, so here we go with a semi-random choice of fundamental concepts about software development process.

I’d like to talk about these topics distilled from my past and present experiences (yeah, more than 20 years…) in a way that’s “less about making the decisions and more about decision-making” (to cite my good friend Matt, our beloved CEO).

What I’m going to explain should be placed especially in the context of a startup, where time and resources are never enough by definition, much more than in a corporate context.

This post is directed mainly to managers and other people that have little or no experience with software production, but could also be useful to all young developers.

I’m going to be very practical, too (I’m not up to the task for theory, go find some good books about it.)

1. Don’t add people to a project lately

Everyone probably knows that “9 women cannot do a baby in 1 month” but not everyone can think the same about software development: put simply, some tasks are not splittable in simpler tasks and so they’re not parallelizable. The direct consequence to this is that adding resources is not always a solution.

But what happens when you add a new person in a team? He’s new to the company, the project, to the tasks he’ll be assigned, but on top of everything else, he’s new in how to contribute new code to the existing code base. So he has to learn, reading docs and code, and he has to ask to everyone else in the company and in his team: this costs time to him and to everyone else, time dedicated to him and no more to the project and the company.

In other words: if adding a resource would imply teaching him/her a very simple process, it would be OK. Software development is never that way, though.

Doing this in a late project makes it later because it steals time to already overloaded people. It seems obvious, but every manager will be tempted to (and most will) add people in a later project.

This is the Brooks’s law.

A similar concept is related to fatigue because the more you work the more you make mistakes. Also, mood will be constantly bad, and you know how’s working with people constantly in a bad mood.

So you work later and later for days or weeks to catch up with work, no weekends, no beers, little family time, and you start to make mistakes and forget things, so you add more work to the work you already had assigned while becoming slower and slower.

Clever.

By the way, it’s the clever thing I always do in a late project even if I know perfectly that it could be the wrong thing to do.

In other words, there’s something going wrong in programmers’ minds so my advice here is to monitor developers and kick them out of the building if they seem too tired.

2. Don’t interrupt people when they’re coding

Interrupting a developer is one of the nastiest things you could do to him as it can have a huge negative impact on his work. This is true for any knowledge worker, but read a couple of articles to understand better the problem in a software development context (the third one is fun, too):

But why interruptions cost so much? I’m citing one of all times hit on programmers’ weirdness:

Working on large abstract systems involves fitting the whole thing into your mind – somebody once likened this to constructing a house out of expensive crystal glass and as soon as someone distracts you, it all comes barreling down and shatters into a thousand pieces.

In other words, loading all that stuff inside a brain requires a time measured in hours.

How could we solve this problem or at least alleviate it? For example, it could be easy to have planned Q&A sessions in which to present questions and doubts in batches to developers.

3. Don’t count your versions before they are released

Software production is tough matter but I’ll make it easy: it’s writing a lot of text to instruct a computer help your customer accomplish some task. As it could easily become a complex task, there are a number of methods and tools used to tame the complexity that emerges as text accumulates, one being product versioning.

A product version can be seen as a set of tasks to be completed before a certain date.

As a convention, each version can have number in the form major.minor.revision (e.g. 1.2.11) and it could be released in phases commonly named alpha, beta, and release (respectively structure complete, feature complete, stable… more or less.)

Each version of the software should pass through a filter that should block the biggest issues and let pass the smallest ones slip away: this filter is called testing. It could be manual or automatic but in any case it should have as output a list of issues solved and not solved. On this lists people who’s accountable for product quality will decide if version will pass to the next phase or not.

Testing is utmost important as it is the wall that must block bad software before it reaches the customer.

For it to work, there should be something to which compare the software to i.e. a specification of what the product is meant to be. And no, it’s not advisable to have your developers test their own code (apart from developing unit tests) because you need a broader QA testing phase in your process.

Another element here is an environment i.e. a piece of infrastructure (web servers, network, database, your mobile phone, a desktop PC, etc.) on which a software runs. You can only use a software product when it gets installed in an environment: installation process in this case is called delivery.

All this is to say: when you hear a programmer say “I’m finished with task x”, don’t think that he means “you can now use/sell/whatever feature x now”, because probably the outcome of his work will be usable by end users after some time i.e. after testing through some intermediate versions (with some back and forth while bugs are being created and squashed) by the corresponding deliveries in the right environments.

The only answer that you’re interested in is probably to the question: “What the delivery date in production environment is?

4. Don’t promise if you cannot keep up with it

In many cases, software release dates are a convention, only something that will help people organize to let a new software version go out of the door.

The release date carries a two-sided message, one internal to the company, an one external directed to the customers. Around this message people and companies could organize some of their activities, sometimes very important. It’s business, you know.

Managers know this well, developers instead tend to ignore the importance of this message, but not because they cannot understand.

In fact, moving a release date is not bad per se, it’s bad because it can break plans.

A release date is a promise and breaking promises is something that you never should want to do.

Exactly as that colleague that arrives always late to meetings, a company that adopts a bad habit of moving release dates again and again gains a bad reputation of being unreliable, this reflects to all the rest of its activities and simply you cannot do serious work with unreliable people.

Managers and other people can help developers and other tech people understand the importance of a date attaching to it all sorts of information about internal and external plans, but the most important thing that could be done is educating people.

The alternative is not making promises when it’s not possible e.g. when work is too much and estimation of a date would be like throwing a dice.

5. Don’t say “it’s easy” if you never did it before

It should be possible to do simple things in a simple way else something smalls bad somewhere, it could be people, tools, process.

As everything is relative, a complex tool for me could be a simple one for you, but when in a non-trivial project that requires some architectural work and a medium/large team, it could not be easy to find the right balance between all the elements.

The rule of thumb is: when in a hurry, never use languages/platforms/frameworks/tools that you don’t know very well, even if in theory they would fit perfectly.

Another little advice is: never work alone when in a team, leverage the power of proximity (physical or even virtual) to solve problems and let your brain consider problems from a distance or from even a very different point of view.

For example, sometimes, when stuck, it’s enough to ask for attention to any of your colleagues to let  the solution magically emerge in your mind (hey, pay attention to avoid too many interruptions though!)

Another good thing that a developer could do as a real boon to his colleagues: never break the build or deliver breaking changes (even if small), especially when approaching a deadline. If absolutely necessary, alert the other people or escalate the decision to the manager.

These are common rules of thumb but so easily and commonly broken (yes, also by myself) that it requires a bit of focus when taking such decisions.

Any manager understanding these problems should enable good behavior by the means of clear rules and also favoring a search for the right tools.

6. Don’t throw dices

Sometimes is better to do than to estimate.

Don’t get it wrong: estimation is a fundamental process in a company, but as more work is there (or as less resources are there,) the more an estimation risks to be not only wrong, but very wrong, leading again to misunderstandings and to bad management.

The question is: is it better having no estimates or a very wrong estimate?

Personally in these cases I prefer to do some work instead of very wrong estimates, but a company/project needs estimates in its life.

Even very wrong estimates are useful because they let management measure and extract some useful information about organization, team, people.

Why programmers hate estimating? In my opinion, apart from the fact that “it isn’t coding“, it’s because it’s a process whose outcomes are always wrong by definition. Instead, the programmer’s mission is to produce programs that always produce correct results. Simply, it’s against their mindset, their experience, maybe also against their nature in some cases: it’s mathematical logic, baby.

In case of estimation requests that you find impossible to fulfill, just give a number using your gut sense but specify that it’s a very inaccurate estimate (yeah, a measure of the error) and commit to go back to it when more information will be available to make a more accurate estimate.

7. Don’t think perfection is something you can achieve – never

When in a hurry (or in a startup) and when there isn’t a clear technical path ahead of you, always choose the fastest path instead of the theoretical “right” path.

This does not mean that the code or the solution have to be rubbish or spaghetti code, but simply that will be the best one achievable with the knowledge already embedded in your brain in that exact moment, which doesn’t require further research or a long trial and error process.

You’ll get a good working solution, now.

You’ll be helping the project become a reality, not only an abstract mental model.

What you could have done (but it isn’t said, it’s relative) is causing your project accumulate some technical debt.

This means that someone in future will have to get rid of your solution and create a new one instead, because your solution, for some reason, was not lucky enough to survive the natural selection caused by evolution on the long term.

It depends on you and also on the recruiting dept (and yes, on many other factors but at the end it’s you that wrote that code.)

Technical debt should be measured and monitored in some way (keeping track of redone parts could be an easy way to measure technical debt) because when it’s too high globally you get a product that is rubbish and, at the very end, it’s also a global measure of how well your company operates.

In general, it’s not bad when it’s low and controlled and it’s simply a consequence of the trade-offs that any project should accept.

The alternative is never release anything. Full stop.

Software development tree swing cartoon