When I graduated (many years ago!) my first job was as a Developer. I was one of about 90 developers on a multi-year project (I think it was in its third year when I joined) and my role required me to churn out code according to the detailed design specification. Follow the design, turn it into C code, make sure it compiled and passed some basic tests then throw it over the wall to the QA team. You won’t be surprised to hear that the project was not a success. In fact, when the company was sold about four years later the new owners discovered two other very similar projects had been underway for about the same time, and none were close to done.
Rather than point out how things could have been far better if they had used an Agile approach, I want to explore how the role of the Developer has changed. Even though we may still use the term these days, the expectations of a Developer have grown significantly. Writing code is just part of the job; as a Software Engineer, the expectation is no longer that of an individual following a design doc and converting it into code then handing it off to the next group in the chain. I’ve seen many argue (and I would agree) that coding is the least challenging part because it’s often what comes naturally as well as being the focus of most training.
Coding is still important, of course, but it’s not where most Engineers need help. Engineers are expected to participate right across the software development lifecycle. They need to be able to talk to their customer and understand the business needs; this used to be the Business Analysts’ role, who would spend a long time learning the domain’s terminology and nuances. They need to take that understanding and merge it with their knowledge of the system; this may require thinking like an Architect, to see not only how to get from where we are to what’s needed to address this particular problem but also to consider how that could impact aspects of the wider system, and even whether that direction is in line with the organisation’s overall technical strategy.
Now they need to implement that design, ideally writing tests first but if not then at least developing tests whilst creating the code. Producing small, testable, incremental steps towards solving the problem; don’t forget to check in with your customer to demonstrate the work in progress and get feedback as often as possible. With the move to DevOps, it’s now also the Engineer’s responsibility to push that code into Production and monitor it so that any adverse events are handled as quickly as possible so as to minimise business impact.
There are probably a lot of things I’ve not included (I know I didn’t mention documentation, UI/UX design, or the many flavours of testing) but my point is that a Developer used to be able to focus on a small step in that process and become an expert in particular languages or techniques; now we expect Software Engineers to be highly competent across a diverse range of skills.
One of the benefits of working in teams is that an individual doesn’t have to be an expert in all those skills – the cross-functional team should contain Engineers with a variety of backgrounds so that the sum of their knowledge covers all the needed areas; diversity of experience, knowledge and interests. We don’t want a team made up of a Business Analyst, an Architect, some Developers, and a QA tester or two – that would just be a mini-waterfall team and would lead to the same flawed processes that I encountered way back when I was starting out.
What we want is a team with at least someone with strong BA skills, someone with design/architecture experiences, and most if not all the team to have an appreciation for testing. And then we want the team to share that knowledge; it’s unlikely all the team members will become experts in all the areas, but they should have enough knowledge so that they can continue to function if a particular domain expert is away for a couple of weeks. We want the team to learn from each other, but that takes time and practice so we should be building that into the expectations of the team, and that means including it when the team is asked to estimate work.
If we expect a team to strive for continuous improvement (in their knowledge, practices, and all aspects of their work) then we need to ensure there’s support to do that. If we constantly focus on delivery or tell a team that they have to hit a deadline, then learning & growth are among the first things that are sacrificed. If leadership doesn’t lead by example and show that they value kaizen and education, then don’t be surprised when the team stops making time to grow.
The role of a software engineer is broad and complex; we need to ensure that we nurture that growth or we’ll revert to having silos of specialists who don’t collaborate, and we’ll wonder why we’re producing poor quality solutions.