I had to cut down the “Pick Your Battles” chapter for my book - reviewers all felt it was too dense. That left me with some extra content, portions of which I’m sharing here, unedited, alongside excerpts I kept in the final version to provide context.
What do Software Engineers Disagree About?
Software engineers can, and do, disagree about anything and everything. I won’t even try to list it all, there is just too much. What I do want to do is give a flavour of the breadth of things we disagree about. Often it’s not even the technical details.
Changing Requirements
Change is inevitable. I’ve already mentioned that being a software engineer is hard. Software is also complicated, but easy to change. If you compare software development to the mechanical aspects of engine design and development (putting aside that all modern engines use a lot of software), the pistons, cylinder, crank shaft, valves, etc. are relatively easy to understand. You can hold and understand the relationships between the components in your head all at the same time. Conversely, software systems have more moving parts (pun intended) and it is often difficult to hold the complexity of just one part of the system in your head, let alone how it all relates to the others. If you need to change something in an engine, the part takes time and cost in people and materials to redesign, manufacture and test. Whereas in software development, you change or throw away the old code and write more code relatively easily.
For example, if your Formula 1 car is racing in Australia tomorrow and you realise you can make the car lighter by redesigning a part, you’re stuck because it has to be redesigned and manufactured back at the factory in the UK and shipped out. However, if you realise you can go faster by changing the point at which a valve in the engine opens, the software can be changed there and then and uploaded into the car in minutes. If the part does arrive in time and it’s not right or it breaks after 10 laps, there’s no time to change it. If the valve timing makes the car go slower, you can change it again in minutes.
The complexity of software means that it is more difficult to predict what is needed and how it will work. It is also easy to change and therefore requires less up front design. Often we, as engineers and the client (the person or organisation who needs the problem solved) learn new things after the development of the software has started and sometimes even as a result of developing the software, and change is then required.
Change is inevitable at all stages of software development and can cause friction and disagreement.
Change often invalidates previous work. Engineers naturally want to feel that their efforts are building towards something stable and valuable. When code is thrown away or rewritten due to changing requirements, it can feel like wasted effort, even if it’s part of a necessary learning process. Multiply this over a large, fast-moving project, and frustration builds, especially if changes seem avoidable or poorly justified.
Timescales
A few years into my career I had a manager who often said “....you’re not working in a vacuum, you know!” They were frustrated because I was always focused on doing what I thought was technically right, without considering the wider organisation. I wasn’t seeing the bigger picture, I was focussed on the engineering, not the purpose of the engineering. This is common in engineers, but gets better with experience.
Organisations have goals and priorities; which they employ software engineers to help meet. Sometimes they shift due to things like changes to the market the organisation operates in, changes in people at the organisation, and for many other reasons. This can mean, for example, that a new feature might need to be delivered in a shorter than ideal space of time or that a new feature may not be released for some time after it is ready. This can cause frustration for software engineers if we don’t feel we can deliver software of the right quality in the timescale or our work feels wasted when it’s ready and not being used.
As with requirements, changes to timescales are inevitable at all stages of software development and can cause friction and disagreement.
I once joined a team late in the year. The organisation was fond of throwing new features at the team in the fourth quarter to make the most of peak sales on Boxing Day. One such feature was given to the team as being simple as it could use a third party API which did most of the work. While this was mostly true, the necessary integrations with the rest of the organisation had been grossly underestimated and the team’s spare capacity had been grossly overestimated. The feature wasn’t delivered. It got put on the back burner until late into the following year, when the team finally delivered the working feature, fully integrated.
The engineers on the team, and not least the team lead, were excited to see the feature go live and understand the extra revenue the feature would bring on Boxing Day. However there was a problem. Over the course of the year the organisation had decided to replace another key system, which the feature was reliant on, and it turned out to be far more complicated than expected. The organisation decided not to put the new feature live until the new system was up and running. Six months later, the feature still wasn’t delivered.
Coding styles
Should an if statement always have curly braces, even if it only contains a single statement? Should you use tabs or spaces for indentation? Should library functions and models be declared close to where they are used or grouped at a higher level? These are examples of things in software engineering which can be considered ‘style’. They don’t cause the software to break, but can, arguably, make the code easier to maintain, read or navigate. Sometimes there are guidelines which cover style, but not always
Take a single if statement as an example. Should it have curly braces:
if (isEnabled) {
doSomething();
}
or not:
if (isEnabled) doSomething();
To prevent going down the proverbial rabbit hole, we’ll ignore the style questions of the curly brace placement and whether the body of the if statement should be on the same line or the next line.
There are two common reasons offered for having curly braces with single line if statements:
Consistency: Multiline if statements have curly braces, so single line if statements should be consistent and have them too.
Prevent bugs: Sometimes, engineers forget to add the curly braces when an if statement becomes multiline. For example:
if (isEnabled) doSomething();
doSomethingElse();
should have been:
if (isEnabled) {
doSomething();
doSomethingElse();
}
but the engineer made a mistake and introduced a bug.
The compiler doesn’t care whether you have curly braces with single line if statements, but engineers often do and disagree.
Which libraries to use
In software development there is usually more than one way to do something. Often, even more so when it comes to choosing a library or libraries for a project. Sometimes there are guidelines for which libraries to use, but not always. Date libraries are one of the most prolific.
Date libraries are complicated things, because dates, time and timezones are complicated things; both in the real world and to model in software. Comparing dates is problematic and a frequent source of bugs at the best of times; even before you throw in daylight saving! NodeJS has a rudimentary date type built in, but doesn’t really help with much beyond representing a date, time and timezone.
Lots of NodeJS engineers use Date-Fn a library which provides a number of functions to assist in manipulating NodeJS’ date type. It’s good, but you’re still working with NodeJS’ rudimentary date type and you need to remember to use the Date-Fn functions. Date-Fn was in wide use on a team I joined as team lead.
I’ve had a particularly good experience with a NodeJS library called Luxon. It’s the natural successor to Moment.js, another popular date library, which is now deprecated. The main advantage of Luxon is that it provides a complete date abstraction, which includes comparison and formatting and easily converts to and from NodeJS’ builtin date type.
When I joined the new team I asked them to start using Luxon instead of Date-Fn and I explained why, much as I have above. But of course some of the engineers were comfortable with Date-Fn, didn’t see the need to change and were reluctant to adopt Luxon, whereas some were willing to try something new.
The disagreement went on for a short while before it was agreed to use Luxon for new features and gradually remove Date-Fn. Choosing a date library in Node.js is an example of classic developer debate. There’s rarely a single "right" answer, and preferences and prior experience are often strong influences.
Non-technical
Many, if not most, software engineers would prefer the majority of their time at work to be spent writing code. That was certainly how I felt for about the first ten years of my career. Unfortunately there is more to working as a software engineer than writing code. As a bare minimum you need to interact with your team, your team lead and/or whoever gives you the requirements. In larger organisations, especially those which are large corporates, there is even more: technical training, non-technical training, team building, large organisation meetups - especially in distributed organisations or those whose staff working remotely or hybrid - having to give a presentation, set personal goals and more.
Engineers are often reluctant to engage in these often soft skills focused activities and it is often a source of friction and disagreement, and difficult to avoid. I’ve included a more detailed example later on.
What colour it should be
If you ask Pink Floyd what colour it should be; they’ll tell you:
“Any Colour You Like”
If you ask Henry Ford of the Ford Motor Company what colour you can have your Model T-Ford; they’ll tell you:
"Any customer can have a car painted any color that he wants so long as it is black."
These two extremes, as well as plenty in between, are also evident in opinions of aesthetics (how it looks), user experience (the way it works) and the consistency of User Interfaces (UI) held by software engineers.
Ideally a team of software engineers also includes a designer who is an expert in how it should look and how it should work. That’s where accountability should lie. Analytics should be used to measure how users interact with a UI and the results of A/B tests used to determine how it looks and how it works. Not every team is this fortunate, however, and even when they are there is often disagreement.
An organisation may be considering two different colour schemes in a rebrand. One or more engineers may prefer one to the other. Two different teams who have components in the same UI may disagree on placement as they have differing and competing driving forces. One engineer may feel it’s better to have an accordion which allows a user to enter their address open when the user lands on the page and another thinks it should be closed. I would expect all engineers to agree that consistency is important: if the button is red on one page, the same button should not be green on another.
When it comes to the way user interfaces look and work there is plenty to disagree about.
Software engineers are bright, experienced people with broad opinions, so they often disagree with each other, their team lead and those around them. However, not all disagreements are worthwhile, so let’s look at what you should consider before you disagree.
Comments
Post a Comment