Software Engineering Principles (Part 2)

In my last post I covered ten technical principles that help engineering teams deliver great software. But this is not the whole story. Teams that build software without a clear purpose, whose time is not respected or work in an unhealthy culture will not be successful. Non-technical principles are just as important as technical ones.

Here are the non-technical principles software engineering teams should follow:

  1. Software should solve a clearly defined problem
  2. Produce technical designs
  3. Follow the Agile Manifesto
  4. Purposeful meetings
  5. Follow simple interviewing techniques
  6. Maintain a healthy team culture

1. Software should solve a clearly defined problem

This should be obvious, but not always! Engineers must be clear why they are building software and what problem it solves. This helps to build empathy for the end user and enables a team to determine the best solution. Having a clear understanding of the problem means we can avoid building things that aren’t required or create technology that is painful to use.

2. Produce technical designs

When building new software there will always be a range of options. Do we need a new microservice or can we modify an existing application? What database does the service need? Do we need a message queue? Can we use serverless technologies or do we need a container orchestration tool?

In order to help teams determine the best solution they should produce technical designs that detail what they are proposing to build. At a minimum this should include:

  • A summary of the problem that needs to be solved
  • A summary of the proposal
  • A breakdown of what software needs to be built or updated
  • Why this solution was chosen

This helps teams to be clear about the rationale for building software and what needs to be done. Most importantly, by having the rationale written down, it enables feedback both within and outside of the team. Assumptions can be questioned, alternative solutions proposed and other tradeoffs realised.

This is not advocating for a waterfall style of software development where every detail is planned upfront and then the entire system is delivered at the end of a particular timeframe. Instead the idea is to outline a course of action that can be iterated on. The design can evolve as new information is gathered.

I am a big fan of the clear and simple architecture approach outlined by Gergely Orosz. Technical designs are also done regularly by tech companies like Google, Amazon, Netflix and Uber and something I’ve advocated in my roles at StatsBomb and EVRYTHNG.

3. Follow the Agile Manifesto

No matter the software development framework we use, we should always strive to follow the principles of the Agile Manifesto.

During my career I’ve worked with various flavours of Scrum and Kanban, some of which have been better than others. At EVRYTHNG we followed this approach that I thought worked well:

  • User stories are defined and prioritised by a tech lead and a product owner before the start of the sprint
  • There is a sprint planning where the team discusses the stories and point them according to complexity
  • Based on the team’s velocity a subset of the stories are taken into the sprint and the team determines the goals of the sprint
  • There is another planning session where the team agrees on the tasks required for each story
  • The sprint lasts for two weeks
  • There is a standup each morning where every team member explains what they did yesterday, what they’re doing today and raise any blockers
  • Any team member should feel comfortable picking up any of the tasks
  • There is a retrospective at the end of the sprint where any team member can suggest improvements to the way the team works. The retro results in a number of actions, each of which is assigned to someone in the team. At the start of the retro the actions of the previous retro are discussed

This approach gives the entire team ownership over what they work on and the goals they want to achieve. It encourages the team to push each other to meet those goals and push back if something threatens them. If a colleague from outside the team wants something else to be worked on, this approach enables frank discussion about the tradeoffs involved and how it could threaten the team’s goals. Progress can also be easily tracked and if the goals are not met it provides a useful discussion in the retro about why that happened.

I am a big believer in avoiding silos during the software development process. Not only should code never have one owner, but understanding the problems the team is trying to solve and what is required to achieve that should also never have one owner. I’ve worked in teams in the past where only the tech lead or the senior developers understood the rationale for what was being built and it led to disillusionment in the rest of the team. Sprint plannings and standups feel like a waste of time for many people because there is no sense of ownership within the team. The Agile approach I’ve outlined, as well as the other principles mentioned in this article, helps to avoid silos during software development. Everyone in the team understands what needs to be done and why, and knows what everyone else is doing. This leads to a virtuous circle of better planning, better standups and better retros.

4. Purposeful meetings

There are two important criteria for meetings:

  1. What is the purpose and/or agenda of the meeting?
  2. What are the expected outcomes of the meeting?

Without a clear purpose meetings are a waste of time. They can get easily sidetracked by unnecessary conversations that will bore or irritate others. Without expected outcomes meetings can end with people dissatisfied and wondering what was the point of it.

There should be a bias against meetings. Before having one we should ask ourselves:

  • Can this be communicated asynchronously either via email or something like Slack?
  • Does the problem require a meeting in order to be solved?
  • Do I need to do more research so that the meeting can be productive?

5. Follow simple interviewing techniques

When bringing new engineers into our team it’s important to have an interview process that is as fair, objective and simple as possible. That means following a structured interviewing technique:

  • Prepare a set of questions related to the job role
  • Ask each candidate the same set of questions in the same order
  • Grade each candidate’s response to the questions

Unstructured interviews often lead to bias and judging candidates on things unrelated to the job. Both Google and Workable go into more detail about structured interviewing and the research that shows how it is a better predictor of on-the-job performance.

6. Maintain a healthy team culture

Engineers will not do their best work if they are scared of making mistakes, worried about raising problems or feel undervalued. Teams must be psychologically safe. They should feel comfortable questioning assumptions and taking risks. Everyone in the team must feel respected and empowered.

People who have a bad attitude and denigrate other’s work hurt team morale and performance. The best software is made by engineers in a healthy team culture. Utilising the knowledge and experience of everyone in the team means they will make better decisions about software.