Left Arrow.Back

Development Cycle

A blueprint of a sci-fi fighter jet.

Notes on the software development cycle from the perspective of a software engineer.

Last Tended
Planted
StatusSeed
2 large squares. Each with a smaller square inside them. 1 square is black, the other white.

Context

I work on a team consisting of:

  • 1 product manager
  • 1 designer
  • 1 person from marketing
  • 5 engineers (senior through to grad)

The team is soley responsible for 1 product & uses an Agile approach including 1-week sprints & daily stand-ups.

A pencil sketch of a sci-fi fighter jet.

1. What

In this step, define what you are going to do. Gather as much information as possible. This step is the foundation of all work preceding it. The more time you can dedicate to this step, the stronger your understanding of the problem, the more likely a solution will present itself & the better everything proceeding it will go.

If I had an hour to solve a problem I'd spend 55 minutes thinking about the problem & five minutes thinking about solutions.
- Albert Einstein
Portrait of Kung Fu master Pai Mei
If we can really understand the problem, the answer will come out of it, because the answer is not separate from the problem.
- Jiddu Krishnamurti
Portrait of Kung Fu master Pai Mei

Have a face-to-face conversation with the information provider (for example, a Product Owner) if possible. You want to remove any communication barriers that come from other mediums, such as lack of body language in written mediums like issue tickets.

  • Rewrite the information in your own words as a list, sketch pictures. Reading information gets you to 1 level of understanding. Parsing it, in your own language, gets you to the next level.
  • Probe the information. Make any gray areas crystal clear. Consider different states:
    • What do we do for:
      • no data
      • large amounts of data
      • bad data
    • Edge cases (what if a user has JavaScript disabled in their browser).
  • Add a persona of a user to your notes (create 1 if none provided) to build empathy.
  • Write out a list of tasks. Each task should be as small as possible but still, deliver some value. This is not an all-or-nothing game. Delivering something of small value is better than attempting to deliver large value & not making it past the finish line.
  • Order the tasks from biggest value to smallest.
  • Go over these tasks with the provider. Confirm the priority & try to catch anything that may have been misinterpreted.

Cost $

In the current web development space, you might jump straight to React as the choice for creating the user interface. I think the composability that comes from React’s component-based architecture is exceptional for scaling complex projects. You could also argue that in today’s society, requirements rapidly change, & choosing a foundation that can scale is a good choice. But benefits come with costs. React increases your bundle size, increasing download time &, when you consider you should try to keep your page load time under 3 seconds, could cost you users. The goal isn't to build the "perfect solution", it’s about building something that has the best pros to cons ratio given the current information. Be aware of the pros & cons of your choices. Document them.

Take Hacker News as an example. A popular tech news site. It has maintained & grown its readership even despite not adding new features over its lifespan. I would argue that React would have been a poor choice for this site. Due to the requirements of this site, the site’s complexity appears low & the cost of increased bundle size & buy-in of a library outweighs the scalability benefit that React provides.

A blueprint of a sci-fi fighter jet.

2. How

This step defines how you are going to do it. Explore:

  • The existing code base (if there is 1).
  • APIs (Hoppscotch can help with this)
  • Documentation
  • Create functions, components, etc... in sandboxes (isolated coding environments). This is especially helpful if your using a library you're unfamiliar with. Tools that can help with this:

If the work involves a mockup, I'll annotate to help the thinking process. I use Excalidraw for this.

Based on the above & requirements, write out what you need to do in pseudocode. You want a clear idea of where you’re going before you start walking. I do this in a .txt file (no styling, just tabs & letters).

2 people working on a frame of a sci-fi fighter jet in a docking bay.

3. Do

Using your pseudocode as a step by step guide, start coding.

Noise

Ekin Öcalan writes that noise can enhance focus & creativity. But it can't be just any kind of noise, it has to be noise that won’t attract your attention. Other people having a conversation or music with lyrics attracts attention while ambient noise, like water lapping the shore, won't. To achieve this, I use noise cancelling headphones combined with Defonic.

Commits

I split a piece of work up into tasks. I aim for a task to take no longer than an hour. I git commit when I complete a task. I think of commits as save points in a video game. They reduce the chance of doing work more than once. When making changes in unfamiliar areas in the codebase & things go wrong. Tests start failing, the console floods with error messages & I'm in over my head. I can clear all my changes & start again from my last save point. Save points give confidence to move fast and break things, knowing the work done up until this point is safe.

These commits are only useful during development. If pushed onto the main branch, they would flood the log with unneeded messages, making it harder to use. When all tasks are complete, before opening a PR, I squash these commits to a single commit using:

> git reset --soft HEAD~3 // squash the last 3 commits
> git commit -m”my commit message”_

For the commit message, I use a convention.

Documentation

Documentation can come in many forms:

  • The code itself by minimizing control flow, using explanatory variable names, & packaging it logically (through modules, files & functions).
  • Comments.
  • Unit tests.
  • External documentation (such as a Confluence page).

In my experience, it’s best to select which approach to use on a problem-by-problem basis, as opposed to a strict policy such as we only write unit tests. Each form has strengths & weaknesses.

Code can describe how, but it cannot explain why.
- Sarah Drasner

Communicating using multiple approaches, such as using code to describe the how & comments to explain the why, can be more fruitful than attempting to be strict & only using 1 approach. Example of a high-quality comment:

Code with comments

Keep in Constant Communication

Its been my experience that this is the longest step in the problem solving process. It can last weeks. Effective teams have a strong shared understanding. Support this by providing updates of the status of your work throughout this step to stakeholders, like product managers. Tools such as morning huddles can help enforce this.

A sci-fi fighter jet with a ladder attached to it in a docking bay.

4. Review

Once you finish coding, walk away. After coding for an extended period of time, you can get tunnel vision. Going deep & solving something complicated while making simple mistakes in the surrounding area. Take a break. Go for a walk. Come back to your work with fresh eyes & check:

  • Does it fulfill all requirements.
  • Can the code be simplified.
  • Can this be maintained.
  • Is the code testable & have tests been written.
  • Performant
  • Documented
  • Secure
  • Scalable
Source
A group of people gathered around a sci-fi fighter jet.

5. PR (pull request)

Submit a PR. To help your team review your work:

  • Size: keep your PR small. The smaller, the easier for reviewers to understand.
  • Title: is a high level description of what's being solved.
  • Description: should guide the reviewer through the code, highlighting related files & grouping them into concepts or problems that are being solved. Use text, mockups, screenshots (before & after), looms. Whatever is best to help communicate.
  • Commit Messages: should talk about what changed & why. Not how (how is in the diff).

Pre-empt questions

As soon as you've opened a PR, you should pre-empt reviewer questions by looking for any potentially surprising changes & adding a line-specific comment explaining why you made the change.
- Mark Dalgleish
Portrait of wizard Gandalf the Gray

Mark isn’t referring to comments explaining a line of code, but to comments that explain a change. Comments that only make sense in a PR context. Comments that explain code belong in the codebase. You can also open a draft PR to enable commenting while not indicating to others your work is ready for review.

When you think everything's understandable, Publish your PR & add reviewers. 1 thing I used to do was to start the next task while waiting for reviews. I think this is a mistake. While working on a problem, you build up context. When you start working on another problem, that context begins to decay. You want to maintain that context until the code has been merged. You want to be able to respond quickly & accurately to any comments or questions as well as confidently make any required changes.

Source
5 circles connected by 20 random lines with no clear pattern.

6. Flexibility

In my experience, the above steps don’t occur in order. Rather, you will be jumping back & forth between them as you start building context in your mind. For example, while coding, you build more of an understanding of what the task requires. Time estimations made in the information step may need to be revisited & tasks removed. A better analogy would be to think of them as nodes in a graph rather than steps on a linear line.

Talking with a designer, they mentioned that this pattern is similiar in his work. The Double Diamond is a popular design process model. On paper, his team uses this model to solve problems & it pleases management when it comes to reporting. However, the Design Squiggle is a more accurate representation of the process.

2 diamonds on the left & a scribble on the right.