Mastering the Software Lifecycle: What Great Developers Do!


I have been in the lucky position that I was able to work with software in different lifecycle phases.

I have been part of large greenfield projects, maintained 20+ years-old codebases, mainly doing damage-limitation and bug fixes, and built products from scratch by myself.

Today, I want to share a few key skills about each stage of software development.

Ideation & Requirements Definition

Often, a new product or project starts with an idea. It’s our job to turn that idea into an implementable software product. What does that mean?

Requirements Engineering. Yes, you’ll scream requirements engineering, and you’re not wrong.

But what is Requirements Engineering?

The most crucial step is understanding the “why” behind the product idea. You’ll need to understand your problem and why you want to solve it.

We often skip the “why” part and jump to the “how” part and design a solution before we even know how this will solve a real-world problem.

Simple questions go a long way. For example:

  • Who are the users?
  • What are their pain points?
  • How are they currently dealing with their problem?

In this phase, tools like storyboarding, requirements documentation, and other loose project management techniques work best.

It’s too early to implement code; spend a fortune on something you won’t need later. I won’t even spend time creating a clickable prototype at this point.

TL;DR: Listening, asking questions, and challenging the status quo.

Planning & Architecture

Before we jump into our favorite IDE and implement the first line, we need to think of a solution design that suits our needs.

We need to choose a technology stack that allows us to solve the problem efficiently and maintain the code base long-term.

We must define the domain, including its main objects, to establish a shared understanding and allow for efficient communication.

We should also consider the development process. How do we test the application? We set up a CI/CD pipeline to efficiently deploy and provide the software to internal testers and other stakeholders.

We might experiment with technologies or tooling to find out whether it will help solve the problem, or if it’s too old or not ready to be adopted in a production application.

TL;DR: Avoid over-engineering from the get-go, but don’t rush to implement your code before considering the broad picture.

Development

We want high-quality, maintainable, and testable software.

We follow development best practices, such as SOLID, use testing frameworks, follow coding conventions, and perform code reviews.

We want to use current, state-of-the-art technologies but don’t want to experiment with untested frameworks. Otherwise, we risk focusing on technology instead of solving the problem.

We create clickable prototypes to ensure we build the right thing before we spend hours building something we (or the users) don’t need.

We often create something that hasn’t been there in code. We need experienced developers who have worked on other software to lay a solid foundation.

TL;DR: Be consistent, implement readable and maintainable code, and build the right thing with the right technology.

Testing & Quality Assurance

The product is almost done. There is pressure to release the software before a deadline.

Even worse, if testers suddenly touch your application for the first time, they flood your backlog with bug fixes and change requests.

Testing shouldn’t be an afterthought in an agile environment with modern development processes.

However, my experience of 20+ years in the industry taught me that no matter how you name your process and how much time you’ll spend testing during development, most testing resources will always be put toward the end of the development phase in most companies.

We need to work closely with the testers. We need to tell them about our decisions and why certain things were built the way they are.

Don’t treat testers as opponents. Treat them as allies and improve the stability and clarity of the application as a team.

But at the same time, we need to reject changes that don’t add value or fix existing issues. We can continually improve the design, layout, UI, etc., but we must release the product first. Version 1 won’t be perfect.

TL;DR: Treat testing as part of the development process. Work with testers, help them understand your decisions, and reject changes that aren’t required to release the software.

Deployment & Release

Great, your code works on your machine. Maybe even on a CI/CD environment - perfect.

It’s time to ship the code to the release environment in the cloud or on-premises at the customer’s site.

Suddenly, you must understand how to set up a server and install and configure your application.

How do you authenticate users? How do users access your systems?

You need to handle server updates, think of how to update your application, and how to get access to log files in case of a reported error.

Automate deployments as much as possible to avoid human error, such as deleting the wrong file or misconfiguring a feature.

Use feature flags to turn off faulty features without deploying a new version. They also allow you to install a new version and delay the activation of a feature to a specific day in the future. It lets you split the physical installation and the activation of new features.

Last but not least, you want to monitor the production environment. Periodically look at the error logs and use monitoring software to react to software crashes or similar problems.

TL;DR: Understand how to deploy and run your application at the customer’s site and how to monitor it.

Maintenance & Support

We want to keep the software healthy and maintainable.

With every bug fix and change request, the code changes, and most of the time, the code base grows.

It’s important to understand the big picture. Even though you might only fix a single checkbox in a form in one corner of the application, you still need to follow the guidelines and implement SOLID code.

Often, implementing the bugfix the right way takes 4X longer than implementing a quick fix. If you don’t do it properly, you’ll find out.

Don’t let juniors fix bugs alone. They might not have the big picture, and even though they do their best, they will need help.

The mistake I often see is that senior developers implement new features, and junior developers fix bugs. It’s a recipe for disaster, I guarantee.

Let your code base evolve, and about 1000 bug fixes later, you’ll declare it unmaintainable if you don’t do it correctly.

Believe me, I’ve been there, I’ve seen it.

TL;DR: Understand how to change an existing system and implement bug fixes without dragging down the performance or maintainability of the software. Age doesn’t rot your code - inadequate program changes do.

Iteration & Growth

Be proactive - not reactive.

Sure, you need to fix the reported errors. But also spend your time exploring opportunities to improve the software. Not only add new features, but also improve the existing ones.

Use data analytics, A/B testing, or other instruments to determine which areas need improvement and which are dead and can be decommissioned.

Always work on the user experience and think of ways to make the application more straightforward to use and less error-prone. A simpler application has fewer bugs and happier users.

Refactor your code and improve the performance of critical processes in your application.

TL;DR: Stay active, stay curious, advocate for best practices, and introduce optimizations where applicable.

Conclusion

The product lifecycle is as diverse as the available programming technologies.

The more mature we get and the more senior we become, the more part of the overall software lifecycle we become.

Embrace it, and understand what skill set helps in what phase.

If you excel in specific phases, let your employer know about it. Work on building the skillset you lack. Software development is a big topic that revolves not only around typing source code.