Making decisions at the right level

cedd burge
RES Software Team
Published in
4 min readDec 11, 2019

RES has an annual staff survey, and cares about the results. One of the lower scoring questions related to “making decisions at the right level”, and we realised that there was little guidance for what decisions programmers were empowered to make.

A previous article explored the importance of programmers making decisions, and this follows up with specific guidance for programmers at RES, detailing what decisions programmers are expected to make, and what decisions should be discussed with the team.

Photo by Jon Tyson on Unsplash

Programming decisions

As discussed in the previous post, schedule pressure is probably the most common reason that programmers don’t make the small scale refactorings that are necessary to avoid the problematic large scale ones.

With this in mind programmers should be empowered to do the following, even if a task is behind schedule. Time and cost are still important issues, so improvements should be expected to take one and a half times the original estimate, and be abandoned if they take longer than two times the original estimate. In this case the issue should be reported back to the team, for prioritisation.

Programmers can decide to:

  • Refactor within the function / class
  • Perform refactorings that span multiple classes
  • Add and refactor tests
  • Use TDD
  • Pair program
  • Make user experience improvements

However, only code that is related to the current task should be modified. This stops us wasting time improving code that might never be looked at or changed again (which isn’t a problem, no matter how terrible it is)

Updating dependencies

Programmers should strive to update dependencies (that is, nuget packages, npm packages, python packages, language versions, framework versions and suchlike) as frequently as they change.

When we update packages frequently, the changes are small, the work is quick and can be taken in our stride.

If it turns out that an update is taking a lot of time, revert the changes and report the issue back to the team for prioritisation.

Ping pong refactoring

Sadly there is no global consensus on how to write code, and it is hard to make one, as the industry is immature and every problem is different.

Different developers may prefer different styles, and it is possible for this to lead to code being repeatedly refactored between the various styles.

This is obviously a waste of time.

To avoid this, we provide the following guidance:

  • Always try to use an automatic code style formatter, such as Prettier
  • Always try to use an automated linter, such as tslint
  • Always try to use an automated static quality analyser, such as Better Code Hub
  • All teams have a Style Guide / Working Agreement, which should be adhered to. Any disagreements and omissions should be discussed with the whole team, and the working agreement should then be updated with the results
  • Consistency is more important than style, so work within the code that is already there
  • However, existing code acts as a template for new code, so if it is genuinely bad it should be improved, to avoid the proliferation of problems

Cost effective coding

Usually when discussing initiatives such as this, concerns are raised about gold plating, over-designing and generally spending too much time on things. These concerns are real and should be addressed. After discussion, we have come up with the following guidance:

Initially code should be written quickly and simply, and should be easy to understand. It should solve only the current problem and not potential future problems. It can contain duplication, and does not need to be easy to change (as it may never need changing). It should generally not contain abstractions, as it is unlikely that there is enough information to design a good abstraction at first. Changes tend to cluster in certain files / classes, so when change requests for a piece of code arrive, we can expect more in the future, which gives us licence to spend more time. We also have concrete information about what the desired change is. At this point we should make the code easier to change, which will probably involve removing duplication and creating abstractions (when enough information has arrived to design them well). This will often make the code more complex, and at least in places harder to understand, so it is a trade-off. Once the code has been made easier to change, the desired change should then be easily made.

Conclusion

Even though the team have Ultimate Responsibility for the state of the code, programmers have the Primary Responsibility. Programmers should strive to break up large problems in to small ones that they are empowered to fix. Making small, incremental improvements is widely regarded to be the best way to write software, and fits in very well with this concept.

--

--