Great Developers go beyond coding

In this article, the Developers at Amazing Outcomes share how they go beyond writing code to be effective and deliver value to their business and their users.

Most of us have the same image of a good Developer in our minds: someone who puts their head down and diligently types away, checking tasks off a list: ticket in, ticket out. They are reliable, productive, and usually keep themselves out of the way. This is all well and good, but we want to challenge this notion by showing how a great Developer can be something more. We want to illustrate how Developers have the power to shape and drive much more than the code they write.

We're Dan and Scott. In our team, we work with Scrum [1] and we do so because we believe it is the best way to deliver more value faster. Scrum is the most effective way to organize product development when the value of the product and the work needed to create it can at times be unpredictable. Ever had a simple code change that ended up taking the whole day to complete because of a domino effect you didn’t expect? Scrum will provide you with a system to re-prioritize your tasks accordingly. And you’ll always know you’ve finished them because of the Definition of Done [2], which ensures not only that you didn’t forget anything, but also that what you’ve produced adheres to the quality and security standards of the rest of your codebase. This is why we value this workflow.

A Scrum team consists of a Product Owner, a Scrum Master, and Developers who have the skills to do the work. We’ll be specifically writing from the point of view of the Developers. Everyone has their role to play, including helping keep each other on track, but our focus is on getting things done more than anything else. The Product Owner has the final decision on what we do, and it’s our responsibility as Developers to figure out how. Doing our job professionally means that we are regularly and responsibly delivering usable Increments [3] that adhere to our Definition of Done (e.g. are functional, secure, compliant, and shippable). We organize our product development into 2-week periods called “Sprints”, and every Sprint we ship at least one new usable version of our product (the Increment) to real users. By shipping new versions frequently, we can deliver value and discover how to further improve the product sooner. That is why we do what we do.

Where the power of a great Developer comes in, is being able to shape not only the code that gets written, but how we fundamentally work as a team. This includes making changes to the status quo of developing. The typical workflow in IT is that each person pulls a task, works on it alone, and tries to integrate it afterwards. That approach often leads to more time being spent integrating than developing - pull-requests blocking other tickets, unintended side effects, not to mention merge conflicts. With that in mind, we decided to experiment with an alternative workflow: what if our default is working together rather than separate? In theory you might think two (or more) people working on one task at a time is slower, but as is so often the case, we found that less multitasking leads to more tasks being completed - at a higher functional and technical quality. It aligns with one of the core principles of value delivery: stop starting and start finishing. Going into the experiment we were afraid that so much pair programming (or ensemble programming[4]) would leave us burnt out, but we found that the opposite happened. Coding with a partner keeps us accountable not only for code quality and knowledge sharing, but also for self care. We found that we took more consistent breaks and finished the work day on time, all while delivering more done Increments in a shorter time than any other team we’d previously worked with.

One key addition to our collaborative coding sessions is the digital whiteboard that we use to bounce ideas off each other. Many times we’d approach a complex task thinking that we already have the same mental plan on how to implement it, only to realize after a few lines of code that we’re miles apart. Out would come the whiteboard, and we would tackle tough architecture decisions before needing to do costly refactorings. A prime example of this is when we implemented a feature sending users an email with a link to activate their accounts. Starting the ticket, we thought, “easy enough!” and got to coding, only to realize there was hidden complexity: what happens if the user opens the link in a different browser, or after they’ve been logged out - how will we know who is attempting to activate their account and whether they’ve been authenticated? It was clear we’d have to allow the user to log in before the activation, but one of us argued we should use a state to remember that the user wants to activate their account after logging in, while the other argued for using a URL parameter. We brought out the whiteboard to list the pros and cons of each approach, and then we realized we could get the best of both by simply reusing our login mask on the activation page - fewer changes, less risky, more robust. When developers are working alone, often these disparities in vision only come up in code reviews, usually after it’s too late to make fundamental changes.

Another advantage of working in pairs (or in an ensemble) is that it empowers us to suggest alternative solutions to the Product Owner. Case in point: recently we were challenged to improve a website’s search engine optimization (SEO). Our original plan was to: “change the codebase to a server-side-rendered (SSR) framework so that we can have a better SEO ranking”. With one Sprint to achieve this, naturally our first brainstorming session was aimed at breaking this down into subtasks. We quickly realized, however, that the goal behind it wasn’t actually to implement SSR: what we were really asked to do was improve ranking. With that distilled goal in mind we took an afternoon’s timebox to research how to make our existing code more SEO friendly and it turns out SSR was not required at all! SEO has evolved since client-side applications became popular and there are many ways to improve your scores without needing big refactors. So we took our findings to our Product Owner, presented our research, and made a case for meeting our goal without SSR. With him on board, we got started on our improvements. A bit of playing around with the URL inspection tool, some tweaks to the HTML tags and robots.txt, and voilà: we got the same results with significantly less work. This is an important role every Developer can fulfill: defying assumptions on how to achieve a goal. A month-long refactoring became a task we finished within 3 days. This was only possible by having the whole team (including the Developers) focusing on the goal, trusting each other’s expertise, and adhering to the DoD.

Really, we’re arguing that our shared concept of a “good Developer” needs an update. A Developer isn’t someone who just writes code. They actively contribute to optimizing the workflow, sharpening communication, and aligning everyone in the team to the goal of ultimately delivering more business and user value sooner. Developers can and should feel empowered to try new approaches to collaboration; our success with pair programming (and ensemble programming) proves that the typical workflow isn’t necessarily the right method. In the end, business and user value come from the teams who produce it, and a great Developer contributes to their team in many impactful ways beyond just coding.

1: (https://www.scrum.org/learning-series/what-is-scrum/)
2: (https://amazing-outcomes.de/en/blog/not-done-not-scrum)
3: (https://amazing-outcomes.de/en/blog/what-is-an-increment)
4: (https://en.wikipedia.org/wiki/Team_programming#Mob_programming)

Build better products faster

Work with our Developers and build better products faster.