September 14, 2020

(Some) Pitfalls in Software Development

A couple of pitfalls that I observed and you, as a developer, should look out for in your projects

Throughout my career I've participated in successes and failures that I pride myself in, with each one unique in it's own way. However, as I progress and mature, I observe similarities in problems over and over again, most of them preventable.

It is easy for us developers to focus on the HOW(technology) instead of the WHY(value) that we should be bringing to our work. The blindspots that you develop, if not careful, will lead to problems for you and your team in the future.

Here are a couple of pitfalls that I observed and you, as a developer, should look out for in your projects.

Frame the following in the context of a software team, some might apply to one-man projects as well.

1. Cost of Innovation

Before starting any project, be careful in picking the technology for your architecture, because everything comes at a cost. There needs to be some sort of stability and foundation to guarantee success in any project. And you don't want to find yourself in the future, pulling hairs, asking why things are the way they are because of your choices.

A great guide I go by is Dan McKinley's - Choose Boring Technology article, where my take aways would be:

Use Boring Technology

"Boring" in this case is the technology your team is already skilled at. If you are in a project that is big and have many moving parts, this is much more important. Boring should also not be conflated with "bad". The good thing about boring is that your team already understands how it works and most importantly, how it fails. The cognitive overhead is greatly reduced when using solutions that you are already familiar with.

Use New Technology, but sparingly

Of course, there will be cases where you would need to use the "right tool" for the job. And new tech fits the bill. However, recognize that once you have spent this innovation "cost", it will be the responsibility of the team.

It is important that this new tech is fully understood by everyone in the team, not just the software developers themselves.

One exercise mentioned in the article is to "consider how you would solve the immediate problem without adding anything new", if you could, with the situation given now. then do not pick that technology.

You don't need Kubernetes ;)

Be conscious of the Team's skill and adaptability.

A big factor for a project's success is the team's adaptability and familiarity of the chosen technology. This will largely affect the quality of the work because the team would know what the best practices should be in use for the solution chosen.

Imagine, choosing Golang for a team of mostly Javascript developers. How effective would the developers be without impacting the project?

2. Maintenance

"It's another team's responsibility..."

This is usually overlooked because of the divide of having a separate team doing the maintenance. As software developers, we've developed the mindset that the application code is ours. Whatever makes it work in production is going to be the responsibility of another team. This is wrong. Every decision we make will affect everyone in the team.

Another factor to be careful of when doing software projects is to ask

  1. Who is going to maintain this feature?
  2. How is it going to affect other parts of the system?
  3. What is the cost of running this in production?

If the team is not aware of this, it is highly likely that they will mostly be...

3. Working without constraints

It's exhilarating to start a project and jump right into creating implementations and features and using the newest, cutting-edge tech out there. Be careful that if you do not incorporate any constraints in your project, you will reap the consequences later.

2 quick questions you can ask to determine some of the constraints are:

  1. What are the boundaries of the Project/Organization?
  2. What are the constraints of the Team?

Remember that there are also 2 sides to software architecture: Business and Tech. And however we may spin it, most of the time, business comes first before tech. This is where the team has to be mindful of the cost of their decisions. the overhead each decision makes. and considerations that should've been made.

A couple of guidelines to start your team on the right track:

  1. Set up your code quality and CI/CD early
  2. Set up your resource consumption budget early
  3. Set up your security/privacy/data handling strategy early
  4. Set up your library/framework/language vetting early
  5. Document and resolve dependencies early
  6. Impose testing as a requirement
  7. Decide and keep to a schedule
  8. Never treat functional requirements as a constraint

Constraints can also be made before starting the project, like:

  • Your organization's vision
  • Your team structure
  • The timeline

4. Fault tolerance as a second thought

"Always engineer your projects as if they will fail at any moment"

It's surprising how many teams i've been on where fault tolerance is not even considered or is put as a secondary concern.

Remember that your software WILL fail at some point in the future, and you'll do yourself service if you think of the following early on in the project:

  1. Perform load tests on your services
  2. Explore the amount of traffic/capacity your services will undergo and assign buffers on them. ie, auto scale via CPU consumption
  3. If able, bake in chaos resiliency in your services
  4. Ensure there is a fallback/rollback strategy when there is an outage

Check out a post I wrote a couple of years back for some idea on how to implement resiliency in your apps.

5. The "Agile" way

Now this is going to be controversial as Agile goes, but I believe this is a misconception a lot of people make due to the intent of being dogmatic with being "Agile".

Doing the ceremonies alone does not make the project agile and exercising any of scrum's tenet's will not ensure the project's success.

Seriously reconsider how the project is run and who is overseeing it if the smells discussed above are apparent. Your retrospectives should be able to pick the smells and your team should be confident enough to make changes. Ultimately, if the customer DOES NOT get the value they asked for or the team keeps missing deadlines, then there is something wrong.

Foster a culture of transparency and openness and this should be easy to remediate.

6. Not recognizing red flags early

Now this is a tricky one. It is quite difficult to recognize the bottlenecks unless you've experienced it yourself directly or indirectly in previous projects. This might as very well be in the "I don't know what I don't know" realm and this is a very hard place to get out of.

This is where listening to your team and your peers will help. Their unique experience can compliment your own and you can definitely recognize what you might be missing. Maintain an open understanding.

Pluralsight recently released a great book on 20 patterns to watch for in your engineering team.

Part 2 is a great read of things that engineering teams often fall into, an excerpt here:

  1. Scope Creep
  2. Flaky Product Ownership
  3. Expanding Refactor
  4. Just One More Thing
  5. Rubber Stamping
  6. Knowledge Silos
  7. Self-Merging PRs
  8. Long-Running PRs
  9. A High Bus Factor
  10. Sprint Retrospectives

Rephrasing the above would never do the book justice, so I highly recommend reading it if you are managing a team.

---

If you are conscious of all of the ones above, it is highly likely that you will make sound decisions and your chance of success will be higher. Of course, the list above is non-exhaustive as I did not talk about observability, monitoring, design, front end, releasing, and testing. Maybe i'll write one in the future :)

Hope the article brings you some enlightenment as it did with me. Hope you are staying indoors and healthy.

This article was originally published in September 14, 2020, here.