The impact of anti-patterns that we faced as a software development team
Tags: Workflow, Agile, Software, Development, Team

1. Not estimating the difficulty of features before kicking off.

Nor did we try to determine the number of features that could be completed within a sprint. Instead, every feature was given a standard time limit of two days, while the number of features selected for a sprint increased as deadlines loomed closer.

Impact:

This approach meant that there was no early feedback on the velocity of the team. We wrongly believed that our workload was satisfactory for months.

When the team finally realized that we were behind schedule, we worked significantly longer hours. Tensions rose, and everyone wondered how they ended up in this mess. Developers felt burnt out and spilled more bugs into the code, which were already frowned upon before but now were stigmatized since we didn’t have the luxury of time to make mistakes.

How being Agile could have helped: Have Iteration Planning Meetings to estimate the difficulty of features and the team’s velocity.

2. Not prioritizing the correct features.

We prioritized features which had the most visibility for stakeholders as well as ease in implementation, rather than those that would ensure a smooth flow of work. For example, features that required coordination and discussions with other teams were put off for a later date.

Impact:

In retrospect (Agile pun intended), this was clearly a mistake as it created further problems when we tried to merge our months of siloed code. It’s easier to add a customized pillar to a building when you’re still working on the foundation than when you’re adding the plumbing.

How being Agile could have helped: Prioritize the features that ensure smooth flow of work.

3. Not keeping stand-ups brief and equally focused on all team members.

We frequently had to endure stand-ups that lasted more than an hour. This was because the meeting was treated as an all-in-one discussion for updates, sign-ups, and problem solving of technical, business and deliverable issues.

Also, many stand-ups were driven by the stakeholder to meet his/her needs. This in turn lead to team members not preparing in advance what they needed to talk about, which further reinforced the stakeholder’s behaviour.

Impact

The two problems together lead to a cascade of further problems, i.e. the broken window syndrome. Long meetings and in-depth discussions of topics not relevant to all team members lead to boredom, and reduced enthusiasm to participate in meetings.

On seeing the reduced enthusiasm, the stakeholder would unintentionally micromanage and police the teams, leading to loss of trust and the feeling of shared responsibility.

How being Agile could have helped: To fix all above problems, the team has to frequently ask “How do we get the most out of a standup?” A standup should be seen as a place to call out coordinated efforts, sharing problems and solutions, building a common understanding of the goal and finally to identify all members as a team.

4. Not tracking open questions.

Given that building a feature is an ongoing, evolving process that encapsulates analysis, development, testing, and refinement, it was important that we should have made allowances for things to go wrong. Unexpected dependencies, logical inconsistencies and deprecated requirements are part of the process. Yet, we treated such incidents as outliers caused by imperfect planning and hastened on.

Impact:

We did not track the problems and open questions on the feature, leading to a variety of questions from teammates and stakeholders:

“Is this feature still in play?”

“Why has it been in play for so long?”

“Should it be put on hold?”

“Wasn’t there a similar feature already that solved this problem?”

How being Agile could have helped: Build a backlog of items, linked to features currently in development.

5. Not blocking a feature that clearly was not making progress.

Continuing with the previous problem, once it was acknowledged that a feature had open questions, we did not mark it as “Blocked”. It stayed in limbo in the Development phase.

Impact:

It delayed feedback to concerned parties that there was a problem that needed addressing right away. The fact that the feature had a problem at all was discovered by stakeholders only when the question was asked “Why aren’t things moving along?”

How being Agile could have helped: Development statuses should be proactively updated and made visible to all parties.

6. Not conferring early and often with a Quality Analyst and a Business Analyst.

After writing code for a new feature, developers would test a feature manually in their local system and push the code into a remote repository. Deployments would then be triggered in the development and QA environments, along with automated tests. Only at this point do the QA and BA review the feature for bugs and completeness.

Impact:

There is an unnecessary delay in feedback in this process. If the QA or BA find a bug, the whole process of ‘write code — push code — deploy’ has to be done again. It compounds for every new bug found. Instead, the developers should have sought preliminary approval from the QA and BA before deploying the code to higher environments.

How being Agile could have helped: Perform Kick Offs and Desk Checks with the QA and BA. And call out that feature is done afterwards. Here is an article that has great checklists for both processes.

7. Not paying back technical debt.

In the early stages of development, while we were still setting conventions and choosing libraries for the code, there wasn’t much technical debt to pay. But in the later stages we were barely writing enough code to stay on track for the deadline. Code that was considered perfect and having zero technical debt was not even a thought on anyone’s mind.

Impact:

Our debt kept compounding, and it started to show. For example, our work would sometimes turn the other team’s pipelines red when the unit test coverage threshold was increased. We would then have to pause development for a day or more to increase coverage across all files. Such a catastrophe could have been avoided had we taken the time to write enough unit tests when developing new features.

How being Agile could have helped: Acknowledge the technical debt, add it to the backlog, and pay it back regularly.

8. Not democratizing knowledge.

On several occasions we realized too late that there were multiple heads solving the same problem at different times, leading to a distorted team understanding of the “Why” of the solution. There was neither a platform nor the encouragement to communicate, collaborate, motivate and inspire each other.

Impact:

The team lost the benefit of combining multiple points of view to arrive at a stronger, collective solution. Instead, many developer hours were wasted, and there were multiple sub-standard solutions, each ignorant of the other.

This also affected the team morale and camaraderie, as one would be inclined to hold his/her teammate responsible for letting them waste their time.

How being Agile could have helped: When you find a challenging problem, discuss it with the team. The team can work out a solution together, and thus everyone has some knowledge of it. Also, record such solutions immediately on any platform that is visible to the whole team.

9. Not stepping back and asking ourselves how we could have done better.

This is probably the biggest mistake we made, because of its domino effect on all the other things we have talked about.

We never stopped and tried to improve our workflow, not even when we had time in the early stages. If we had held retros regularly, we would have been in the position to ask ourselves simple questions with illuminating answers.

“Are we making good progress?”

“Are we finishing enough stories in each sprint to meet our deadline?”

“Are we spending more time firefighting than being business as usual?”

And we would also have taken the time to congratulate ourselves regularly on the things that went well, instead of celebrating only months later, after the product goes live and everyone is exhausted from working 60+ hours a week.

Impact:

On the surface you might feel fine, but by performing a few routine checks we can nip off tiny red flags that would’ve otherwise morphed into something worse. Another way to think of it is in terms of entropy. Over time, any system becomes messy. If you are not making efforts to improve your code even a little bit, it is getting worse by default.