Trust me, I’m a developer
The question is, what’s in this picture that convey an idea? Which are the key elements that identify a developer?
Thinking about that, I’ve put together a set of characteristics that I do believe are relevant for our profession.
Before going through the five of them, it’s important to observe that there may be other elements that could be added to the set, the intent is not to define new Tables of the Law, carved in stone. And, by recognizing these characteristics as relevant, doesn’t mean to be able to satisfy them all. The set should be interpreted as a goal to which aspire.
Characteristic 1 — Simple solutions
Thinking in a complicated way is typical of several developers. It’s quite natural, since it’s more obvious to make things complicated, rather than simple …
Starting with a complicated solution and then simplify it could represent a good compromise. I call this approach “mass the code until you can see its essence”.
It’s a bit like putting order in your basement, every once in a while: you start to put stuff in, but soon you’re not able anymore to make sense of it. Therefore, on a regular base, you have to face it and try to kick in some order and throw away useless stuff. The same happens with code: you start with a working solution, that is rather complicated, than, little by little, you work along the way to make more functional and clean; you do refactoring. That is neither simple nor immediate: simplicity is an art, as stated by Agile Manifesto.
Refine architecture and design
That’s why we embrace the concepts of emergent architecture and design, continuously refined along the project’s solution. My advice is to select your own architectural style, being at the same time open to evolutions, whenever these would lead to simplify to product. Summarizing, it’s useless to overdesign a solution since the beginning, applying concepts that cannot be immediately applied. They will naturally emerge during development.
Be wary of frameworks, even if they appear to be the fastest solution, they not always are in the long term. It’s better to adopt them when the framework’s patterns do emerge during development, otherwise you will be constrained by stuff that is not being used.
Characteristic 2 — Balancing Technical Debt and Business Value
How many times did you found yourself entangled in this dilemma? ”You’re going to release it into production, right? Therefore add also this, please. It’s really important for our users, like life or death. Without it the next release would be worthless …”.
Trying to stay away from this kind of situation has become almost instinctive for a developer. To introduce a patch “on the fly”, during a software release, will almost certainly increase the amount of technical debt and related production time risks, since there is barely time enough to just introduce the patch. In such way, frictions between development and business do rise, and so do endless discussions, making things worse …
Compute Technical Debt
A developer should be able to face this kind of confrontation with a systematic and objective approach. We can express “objective” by a formula.
Technical debt. Green is the ideal curve of technical debt. Red is the real curve.
Cost of delay. Green is the ideal curve of release. Red is the real curve when you release in delay.
If, by adding a patch on the fly, the technical debt is increased by ∆D, the value for the end customer is improved by ∆V, and the cost of repaying the technical debt’s increment is ∆R, then the condition
∆V — ∆D > ∆R
must be true, in order to proceed with the inclusion of the patch.
Otherwise the outcome will result in waste of money and it will better not to add it. There is no one in the company willing to throw money out of the window, and by grounding the discussion on facts, the dialogue will be smoother.
In order for the formula to be accurate, the concept of technical debt should include also the cost of delay. But we’ll address it at some other time.
Characteristic 3 — Test Driven Development
We can all agree that testing is really important. If tests are automated is even better.
Our agreement starts to fade away about the fact that writing tests beforehand is of crucial importance. Better, we all agree in principle, but in everyday life, facts do demonstrate the opposite: we don’t write enough of them!
Tests are important and they should drive “intelligent” development
TDD advantages
Test Driven Development (TDD) is not only a good testing practice, but, in the end, it’s a practice to write better code.
By “better code” I mean:
easy to understand, since writing test forces to reflect more carefully about naming, patterns and responsibilities;
easier to maintain, since test is a safety net for anybody that will be in need to work on that code, after you;
documented, since tests do state in a clear and objective manner the intent of code, better of any design document;
simple, since TDD is implemented in small incremental steps, and each step includes refactoring.
TDD’s goal is to write better code
The only issue, is that you must be really rigorous in order to apply TDD approach.
Therefore: train yourself, train yourself (again) and do implement tests since the beginning! The first line of code you write should be a test! You can say “OK. Cool, but in reality that doesn’t happen …” and you’re right. I’ve to repeat it to me each and every time, and force me to do it. But, as soon as I do results are clear and I blame myself for not doing it every time I code.
Characteristic 4 — Automate everything, since the beginning
I trust that everyone of us has experienced, at least once, the thrill of release to production. But such thrill, if lived through several times a day, may become a source of stress.
Mistakes, forgetfulness, incompatibilities of configurations are only on handful of the stumbling blocks that we may fell upon at release time. How can we overcome this? Let’s automate everything and, even better, let’s embrace an “Automation Driven Development”.
Similarly to TDD, when I first write test and, only after, code, my proposal is to write automation since the beginning, otherwise it will be very difficult to do it and verify its correctness when the codebase becomes relevant.
Automation is key to high quality development
Automation Driven Development
That’s why, during Sprint 0, it’s important to refrain from manual activities and to automate the “hello world” application, implemented on your reference architecture, by:
- implementing automatic build, updating all libraries from source code repository (npm, Maven or other); don’t copy libraries manually;
- having the whole test chain up and running, not limited to Unit Tests only, including Production Tests;
- running static code analysis, with linters that enforce coding style and reduce the possibility of oversights
- adopting an appropriate branch strategy, the simpler the better: use trunk based development or feature branches, merging on temporary branches in order to prevent feature branches to divert, and make their lifecycle as short as possible;
- implementing a continuous chain: integration, delivery and deploy
- linking “Done” stories in the Product Backlog to the build, in order to be able to understand what has been released by when;
- defining of an adequate code versioning policy;
- introducing loggers and analytics functionalities, so that crash logs and usage data, by end users or other systems (M2M), are recorded
This list could go on and on. For instance, we could add automatic machine creation with Ansible, Vagrant and Docker. But it’s better to stop here. The idea should be clear, by now: every time a task can be automated, let’s do it straight away!
Characteristic 5 — Let’s fall in love with end users and not with technology!
Last, but not least, there is the technology; as charming as it can be, let’s not follow any new lead, nor let’s stay grounded to what we know already, but let’s endlessly explore! The ability to decide between when to dare and when not is the mark of a good developer.
A good developer should strike a balance between sensitivity, curiosity, technical competence, passion and other talents
A passionate developer is curious and always look for solutions that are innovative, neat and technologically advanced. This is a positive approach, that should be sustained and sponsored, but with a specific care: always balance innovation and end user’s benefit. It’s worth to remember that software is the mean to address the users’ needs, and not the end.
That’s why a technological solution is good whenever is transparent to the end user.
Following this simple rule, it’s relatively easy to make the choice between daring and having a conservative approach.
Technology can simplify, speed up and make more robust a digital service. The greater technological innovation is, the most such characteristics will be amplified. Therefore, a developer should write any single line of code taking in account if such line will simplify things for the user, human or machine. If that shouldn’t be the case, then that could be an useless line.
Conclusions
We have been striving to define a set of characteristics and practices useful in order to define what a quality developer is:
- Simple solutions
- Balance between Technical Debt and Business Value
- Test Driven Development
- Automate everything, since start
- Let’s fall in love with end users and not with technology!
Certainly, such set can be improved upon and extended, but our aim is to foster reflection and start conversation
Code on!
Credits
This article has been published by me the first time on Linkedin in italian https://www.linkedin.com/pulse/trust-me-im-developer-giulio-roggero
Thanks to Giuseppe Ferrario, professional illustrator for effigie.it, that managed very well the blending of different elements of the puzzle of the sticker.
A big thank you to Renato Brazioli for the translation in English!
The 5 key elements have been presented at the Agile O’Day Napoli in 2017 https://www.slideshare.net/GiulioRoggero/trust-me-im-a-developer.