On Software Design Sessions...
How to improve shared context and software craftsmanship
Periodically, our squad engages in what we call “Nitro Days.” These are days where we book a conference room and work together, away from our desks. The purpose of these days is to encourage a singular focus on a shared problem, free of the normal distractions of other meetings and drop-ins. If you’ve ever played the Need for Speed games and hit the NOS, think of that. It helps us get an extra boost on our work.
In one of these sessions a few months back, we were working out how to build an API authentication flow. I had the thought, “this would be a great use-case for a UML sequence diagram.” I shared that with the team, so we got to diagramming the whole process out. We went further, diagramming a flowchart for the module logic.
So what were the results? Within thirty minutes after the discussion, we had a working solution coded and code-reviewed. And just as valuable, every engineer on the squad understood the problem; they understood the solution. Even though it was one person on the team that directly coded.
What I realized later was that we stumbled into conducting a software design session. With this post, I want to advocate the benefit of a pause before coding, just to take a little time to work out solutions with your team.
To begin, I want to contrast this method of working with what in my experience is often the default. The default pattern usually goes something like this:
The developer is assigned a ticket
Developer reads ticket.
The developer immediately starts coding in isolation.
If code reviews are required (and they should be), the developer submits a pr
The developer gets feedback and may refactor the solution if needed.
Do you see the problem with this? It’s not until the code review after code is worked on, that peer review and solution discussion occurs. If more of this can be front-loaded before fingers have touched keys. context is much more effectively shared, multiple voices speak into solutions, coding itself goes faster, and code review is more friction-less since the reviewer is working from the same context.
Since that nitro day, we’ve practiced this in various forms and formats. Here are a few benefits that I’ve observed over time doing this:
Teaching and learning opportunities for craftsmanship.
Improved software craftsmanship across the team.
Highlights assumptions and potential risks.
Gives the team a jump-start on documentation.
Let’s examine each of these a bit...
1. Shared Context
I’ve already spoken on this up to this point. To me, the biggest advantage of this practice is that it is natural. A big problem that can easily occur is siloing of information. How often is it that one engineer on the team understands a particular system or process, they go on vacation, leave, or are otherwise unavailable? As soon as that happens, the rest of the team is left scrambling to figure out how the hell the damn thing works when they inevitably must work on said system. Engaging in design sessions regularly can help interrupt that siloing effect.
2. Opportunity for Teaching and Learning
In the first session, I had just learned about sequence diagrams from a course I had been taking. This provided me with an outlet and opportunity to share that knowledge with the team. This makes that training way more valuable, because it’s not just myself that is benefiting from it, it’s the rest of the team.
In a more recent meeting, we learned about the Factory Pattern and applied that to a problem solution. Not just one person. The whole team.
In these sessions, it’s often that someone has a unique take or perspective on the problem and how to solve it. This provides a natural opportunity for them to share this perspective and perhaps teach a new software engineering technique. This is so much more powerful because it is in the context of a problem we are working on, rather than a dry textbook example.
3. Improved Software Craftsmanship
This is similar to the last point but restated from a different angle. Because a natural opportunity is presented to teach and share, the level of craftsmanship rises not just with the individual developers on the team, but with everyone. Everyone starts speaking in the same language. Junior developers and more senior developers are speaking in terms of design patterns and behavior modeling techniques.
4. Highlights Assumptions and Potential Risks
Often, a problem may seem simple on the surface. For example, a requirement may be that your code must send an email based on some user action. People send emails all the time, this shouldn’t be difficult.
With a design session, questions can start being asked... Who designs and develops the email template? What system is it that sends the email? Are there any external dependencies? What are the various options available?
Then with the answers to these questions, your team can graphically map out on paper what the dependencies are and where they introduce risk to the project. Unknown assumptions are brought to light through this process.
5. Jump-start on documentation
After that initial white-boarding session, we took it a bit further and formalized our sequence diagram in Lucidchart. This gave us a design artifact that we could store with the code and use to document and discuss the solution later.
Documentation is often an afterthought when writing software. When diagramming and communicating about solutions before building, the team is already primed into a documentation-oriented mindset. And it is much easier to go back to the already existing designs after the project, edit and archive them than it is to have a completely separate body of documentation work.
Now, if a UML expert were to come by and examine our charts, they’d probably find all sorts of problems. Being perfect at UML wasn’t the point. The point was to grapple with the problem outside of our heads in a shared space so that the team could engage in the same mental model with a shared context.
6. It’s Fun
Finally, It’s just fun. I think of software design discussions as riffing sessions.
In the same way that jazz musicians would come together and instantaneously create music, developers are coming together, improvising designs and discussing ideas on a whiteboard. Like a set of skilled musicians, we are drawing from our own shared set of language and experience to make something new in real-time. The software and the documentation then become the recording of a great jam session.
One problem I’m still wrestling with solving: How can we work this way as a squad without the need for a meeting? Meetings aren’t entirely evil, but they can be inefficient. My ideal vision is that instead of having to book a meeting, this method becomes the normal way we work. Whenever we start working on a problem, instead of immediately coding, we spin around, start marking up a whiteboard and start a discussion.