Writing good software
Making user facing software is usually about creating tools that augment human cognitive or organizational abilities, such as memory, calculation, collaboration, communication and prediction.
Users hire products, in this case software, to get a job done , for example moving from A to B, finding out when Roger Waters will be in town, getting fed, staying in touch, having fun, and paying employees.
Product development is about identifying the problems, jobs to be done and tasks that a person wants to achieve and proposing a much better solution for them than the status quo.
Software creation or software development is about creating the tools that implement the proposed solution.
With a fixed amount of resources (mainly people, time and money) there are 3 main areas to take into account when developing software: quality (does it work?), scope (is it done?) and time (when will it be done?)
Does it work? 
To gauge quality we can ask some of the following questions: Is the software useful? Does it solve a real problem? Is it easy or even delightful to use? Does it get the job done correctly? Is it available when it needs to be used? Is it fast?
Software writing is a human endeavor and as such is prone to human error.
That means itâs unusually hard (perhaps impossible) to create error free software.
To illustrate the point just look at the comments whenever you update your smartphone apps, youâll find a lot of bug fixing in there. Even on mission critical systems, such as operating systems, networking libraries or servers there is a constant fixing of known bugs and security vulnerabilities are frequently discovered . Fixing bugs is a lot of work and there will probably always be unknown errors and vulnerabilities to be discovered.
So weâd rather assume software is never 100% error free.Â
What we can try to do is to minimize the introduction of errors. For that there are best practices that have evolved, most are about managing complexity.Â
Is it done?
A piece of software has a set of functionalities that it should perform, weâll call this the scope, and a set of functionalities that it can perform, weâll call this capability.
The objective is to achieve scope-capability parity.
A clear and stable scope helps developers focus on a finite set of functionalities.Â
A much better question to ask, rather than âis it done?â is âis this piece of the scope covered?â. We can clearly compare what was specified versus how the software operates and calculate a coverage percentage that is hopefully as close as possible.
But we should never assume that a piece of software is done. Done as in finished. Why not?
Because all software can be expanded to have more functionality, or contracted to have less, also technologies and platforms are in constant state of change.Â
New technologies emerge, new form factors (screen, voice, touch) are introduced, user interfaces (mobile, web browsers, VR, bots), storage technologies (relational databases, SSDs), runtimes (virtual machines, containers), operating systems (android, iOS, arduino, symbian, blackberry, windows, macos, linux, unix, freebsd), frameworks (orm, mvc, reactive), protocols (http, https, http2, blockchain, bittorrent), to name a few.
That means there is an inherent maintenance activity of keeping software current and available for new platforms. Considering human wants and needs are ever changing and the platforms upon which software runs keep improving we conclude that software is never done.
When will it be finished?
Estimation is the art of peeking into the future and should be used with care. Any creative activity is inherently undefined. Consider the difference between following a recipe and inventing one. Or even solving an equation and writing it. Following a recipe is easily estimated, inventing one is not. Letâs rather think of estimation as a mere guess.Â
The main reason estimating is hard is that itâs hard to know beforehand what the series of steps to create a piece of software will be at the required quality level. Same as with a recipe, or a poem or an equation. Itâs about the unknown unknowns.
Consider the following exercise:
How long would it take you to write a poem that someone will be willing to pay $10 usd to listen to? What about one that can win a prize?
If weâre kind to the poem writer, we might tell them the language it needs to be written in, the minimum and maximum lengths, the topic, whether it can have music or not and other specifications. Still there will be unknowns, can we copy one? Is it easy to read? who is it for? should it be printed, painted on a wall, put online? can it contain adult material? can the user pay later? should the user be able to see a preview of the poem before buying?
Now can you give an estimate for prize winning poem writing? A range? How accurate?
Various attempts have been made to be able to estimate better, one of the best ones is
Evidence Base Scheduling , where the output of the estimation process consists of constantly changing estimate curves based on individual historical estimation accuracy and progress. If you need an estimate no matter what, then a probability curve is the closest to an estimation youâll get.
What can we do if estimating is so hard?Â
The agile school of thought proposes setting the time (sprints) and resources (team) to a fixed amount, usually a 3 week sprint and as few as 1 and up to 8 people, and making the scope variable.
Others despise the agile development process and opt for a best effort process, where contributors work on whatever they deem most important according to their objectives and incentive structure .
Furthermore, research has shown that small tight teams tend to perform better than large teams and that adding people to a late project only makes it slower.
If we think about the fundamentals in terms of physics, where velocity = distance / time. Then if we want to get to a certain distance (scope) with a certain amount of resources (time), then perhaps we can try to optimize for velocity.
What does moving fast mean in terms of software development?Â
Like any creative activity, writing software requires long periods of concentration. Developers are on a makerâs schedule whereas the world around them is on a managerâs schedule. Then one way to make sure progress is made as fast as possible is to minimize distractions.
Developers, even if they sometimes seem cold, socially awkward and quiet, are people, and people need to be motivated by the problem they are solving. In general itâs important to make sure their voice is heard and that they believe that what is being created is worthwhile. They also like to learn and work with other people that they can learn something from and with whom they can create something together.
Finally we have arrived at an approach to enable makers to work as fast as possible.
Summary
Software is never perfect. :/
Software is never done. :/
Estimating is hard. :/
Good software can be developed as fast as possible by small, happy, capable and focused teams. :)
